diff --git a/README.md b/README.md
index d7f0bb7..c5e5e6b 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
# Argo Api Authn
- [![Build Status](https://jenkins.argo.grnet.gr/job/argo-api-authn_devel/badge/icon)](https://jenkins.argo.grnet.gr/job/argo-api-authn_devel)
+[![Build Status](https://jenkins.einfra.grnet.gr/buildStatus/icon?job=ARGO%2Fargo-api-authn%2Fmaster&style=flat-square&color=darkturquoise&subject=build-master)](https://jenkins.einfra.grnet.gr/job/ARGO/job/argo-api-authn/job/master/)
+[![Build Status](https://jenkins.einfra.grnet.gr/buildStatus/icon?job=ARGO%2Fargo-api-authn%2Fdevel&style=flat-square&subject=build-devel)](https://jenkins.einfra.grnet.gr/job/ARGO/job/argo-api-authn/job/devel/)
Authentication Service for ARGO API(s)
@@ -75,7 +76,7 @@ Before you start, you need to issue a valid certificate.
"trust_unknown_cas": false,
"verify_certificate": true,
"service_types_paths": {
- "ams": "/v1/users:byUUID/{{identifier}}?key={{access_key}}",
+ "ams": "/v1/users:byUUID/{{identifier}}",
"web-api": "/api/v2/users:byID/{{identifier}}?export=flat"
},
"service_types_retrieval_fields": {
@@ -127,4 +128,4 @@ but a reverse dns look up returns another hostname for the client from where the
- ~~Add default configuration for interacting easier with the [argo-web-api](https://github.com/ARGOeu/argo-web-api).~~
-- Add support for using OIDC tokens as an alternative authentication mechanism.
\ No newline at end of file
+- Add support for using OIDC tokens as an alternative authentication mechanism.
diff --git a/argo-api-authn.spec b/argo-api-authn.spec
index 07755ce..868141d 100644
--- a/argo-api-authn.spec
+++ b/argo-api-authn.spec
@@ -3,7 +3,7 @@
Name: argo-api-authn
Summary: ARGO Authentication API. Map X509, OICD to token.
-Version: 0.1.8
+Version: 1.0.0
Release: 1%{?dist}
License: ASL 2.0
Buildroot: %{_tmppath}/%{name}-buildroot
@@ -57,6 +57,8 @@ go clean
%attr(0644,root,root) /usr/lib/systemd/system/argo-api-authn.service
%changelog
+* Mon Oct 10 2022 Agelos Tsalapatis - 1.0.0-1%{?dist}
+- Release of argo-api-authn version 1.0.0
* Mon Nov 8 2021 Agelos Tsalapatis - 0.1.8-1%{?dist}
- Release of argo-api-authn version 0.1.8
* Tue Apr 13 2021 Agelos Tsalapatis - 0.1.7-1%{?dist}
diff --git a/auth/certificate.go b/auth/certificate.go
index 96cd4b7..6e05f5b 100644
--- a/auth/certificate.go
+++ b/auth/certificate.go
@@ -64,7 +64,7 @@ func LoadCAs(dir string) (roots *x509.CertPool) {
).Error("Error walking certificate system path")
} else {
log.WithFields(
- log.Fields{},
+ log.Fields{"type": "service_log"},
).Info("All certificates parsed successfully!")
}
diff --git a/authmethods/api_key_auth.go b/authmethods/api_key_auth.go
index 185f99e..0cf3a16 100644
--- a/authmethods/api_key_auth.go
+++ b/authmethods/api_key_auth.go
@@ -57,7 +57,7 @@ func (m *ApiKeyAuthMethod) Update(r io.ReadCloser) (AuthMethod, error) {
var authMBytes []byte
var tempAM TempApiKeyAuthMethod
- var updatedAM = NewApiKeyAuthMethod()
+ var updatedAM = &ApiKeyAuthMethod{}
// first fill the temp auth method with the already existing data
// convert the existing auth method to bytes
@@ -104,6 +104,7 @@ func (m *ApiKeyAuthMethod) Update(r io.ReadCloser) (AuthMethod, error) {
return updatedAM, err
}
+ updatedAM.UpdatedOn = utils.ZuluTimeNow()
return updatedAM, err
}
diff --git a/authmethods/api_key_auth_test.go b/authmethods/api_key_auth_test.go
index 0500381..7e3f825 100644
--- a/authmethods/api_key_auth_test.go
+++ b/authmethods/api_key_auth_test.go
@@ -66,7 +66,7 @@ func (suite *ApiKeyAuthMethodTestSuite) TestApiKeyAuthFinder() {
func (suite *ApiKeyAuthMethodTestSuite) TestUpdate() {
- apk1 := ApiKeyAuthMethod{}
+ apk1 := &ApiKeyAuthMethod{}
ba1 := BasicAuthMethod{ServiceUUID: "uuid1", Host: "host1", Port: 9000, Type: "api-key"}
apk1.BasicAuthMethod = ba1
@@ -76,6 +76,8 @@ func (suite *ApiKeyAuthMethodTestSuite) TestUpdate() {
apkUpd1.BasicAuthMethod = baUpd1
r1 := ConvertAuthMethodToReadCloser(apkUpd1)
a1, err1 := apk1.Update(r1)
+ ca1 := a1.(*ApiKeyAuthMethod)
+ apkUpd1.UpdatedOn = ca1.UpdatedOn
// update fields that aren't supposed to be updated
apkUpd2 := &ApiKeyAuthMethod{}
@@ -83,9 +85,11 @@ func (suite *ApiKeyAuthMethodTestSuite) TestUpdate() {
apkUpd2.BasicAuthMethod = baUpd2
r2 := ConvertAuthMethodToReadCloser(apkUpd2)
a2, err2 := apk1.Update(r2)
+ ca2 := a2.(*ApiKeyAuthMethod)
+ apk1.UpdatedOn = ca2.UpdatedOn
suite.Equal(apkUpd1, a1)
- suite.NotEqual(apk1, a2)
+ suite.Equal(apk1, a2)
suite.Nil(err1)
suite.Nil(err2)
diff --git a/authmethods/authmethods_test.go b/authmethods/authmethods_test.go
index 277cc3b..4476ffb 100644
--- a/authmethods/authmethods_test.go
+++ b/authmethods/authmethods_test.go
@@ -195,6 +195,8 @@ func (suite *AuthMethodsTestSuite) TestAuthMethodUpdate() {
amU1.BasicAuthMethod = ambU1
r1 := ConvertAuthMethodToReadCloser(amU1)
a1, err1 := AuthMethodUpdate(am1, r1, mockstore)
+ ca1 := a1.(*ApiKeyAuthMethod)
+ amU1.UpdatedOn = ca1.UpdatedOn
// normal case - update fields that can't be updated
ambU2 := BasicAuthMethod{ServiceUUID: "uuid1", Host: "host1", Port: 9000, Type: "some_api-key", UUID: "some_am_uuid_1", CreatedOn: "some_time"}
@@ -202,6 +204,8 @@ func (suite *AuthMethodsTestSuite) TestAuthMethodUpdate() {
amU2.BasicAuthMethod = ambU2
r2 := ConvertAuthMethodToReadCloser(amU2)
a2, err2 := AuthMethodUpdate(am1, r2, mockstore)
+ amU2.UpdatedOn = ca1.UpdatedOn
+ am1.UpdatedOn = ca1.UpdatedOn
// unknown service uuid
ambU3 := BasicAuthMethod{ServiceUUID: "unknown", Host: "host1", Port: 9000, Type: "api-key", UUID: "am_uuid_1", CreatedOn: ""}
@@ -209,6 +213,7 @@ func (suite *AuthMethodsTestSuite) TestAuthMethodUpdate() {
amU3.BasicAuthMethod = ambU3
r3 := ConvertAuthMethodToReadCloser(amU3)
a3, err3 := AuthMethodUpdate(am1, r3, mockstore)
+ amU3.UpdatedOn = ca1.UpdatedOn
// unknown host
ambU4 := BasicAuthMethod{ServiceUUID: "uuid1", Host: "unknown", Port: 9000, Type: "api-key", UUID: "am_uuid_1", CreatedOn: ""}
@@ -216,6 +221,7 @@ func (suite *AuthMethodsTestSuite) TestAuthMethodUpdate() {
amU4.BasicAuthMethod = ambU4
r4 := ConvertAuthMethodToReadCloser(amU4)
a4, err4 := AuthMethodUpdate(am1, r4, mockstore)
+ amU4.UpdatedOn = ca1.UpdatedOn
// empty service uuid
ambU6 := BasicAuthMethod{ServiceUUID: "", Host: "host1", Port: 9000, Type: "api-key", UUID: "am_uuid_1", CreatedOn: ""}
@@ -223,6 +229,7 @@ func (suite *AuthMethodsTestSuite) TestAuthMethodUpdate() {
amU6.BasicAuthMethod = ambU6
r6 := ConvertAuthMethodToReadCloser(amU6)
a6, err6 := AuthMethodUpdate(am1, r6, mockstore)
+ amU6.UpdatedOn = ca1.UpdatedOn
// empty host
ambU7 := BasicAuthMethod{ServiceUUID: "uuid1", Host: "", Port: 9000, Type: "api-key", UUID: "am_uuid_1", CreatedOn: ""}
@@ -230,6 +237,7 @@ func (suite *AuthMethodsTestSuite) TestAuthMethodUpdate() {
amU7.BasicAuthMethod = ambU7
r7 := ConvertAuthMethodToReadCloser(amU7)
a7, err7 := AuthMethodUpdate(am1, r7, mockstore)
+ amU7.UpdatedOn = ca1.UpdatedOn
// empty port
ambU8 := BasicAuthMethod{ServiceUUID: "uuid1", Host: "host1", Port: 0, Type: "api-key", UUID: "am_uuid_1", CreatedOn: ""}
@@ -237,6 +245,7 @@ func (suite *AuthMethodsTestSuite) TestAuthMethodUpdate() {
amU8.BasicAuthMethod = ambU8
r8 := ConvertAuthMethodToReadCloser(amU8)
a8, err8 := AuthMethodUpdate(am1, r8, mockstore)
+ amU8.UpdatedOn = ca1.UpdatedOn
// empty access key
ambU10 := BasicAuthMethod{ServiceUUID: "uuid1", Host: "host1", Port: 10000, Type: "api-key", UUID: "am_uuid_1", CreatedOn: ""}
@@ -244,6 +253,7 @@ func (suite *AuthMethodsTestSuite) TestAuthMethodUpdate() {
amU10.BasicAuthMethod = ambU10
r10 := ConvertAuthMethodToReadCloser(amU10)
a10, err10 := AuthMethodUpdate(am1, r10, mockstore)
+ amU10.UpdatedOn = ca1.UpdatedOn
// auth method for host and service already exists
amb2 := BasicAuthMethod{ServiceUUID: "uuid1", Host: "host1", Port: 9000, Type: "api-key", UUID: "am_uuid_1", CreatedOn: ""}
@@ -254,6 +264,7 @@ func (suite *AuthMethodsTestSuite) TestAuthMethodUpdate() {
amU11.BasicAuthMethod = ambU11
r11 := ConvertAuthMethodToReadCloser(amU11)
a11, err11 := AuthMethodUpdate(am2, r11, mockstore)
+ amU11.UpdatedOn = ca1.UpdatedOn
suite.Equal(a1, amU1)
suite.Equal(a2, am1)
diff --git a/authmethods/basic_auth_method.go b/authmethods/basic_auth_method.go
index cc564a6..54221c9 100644
--- a/authmethods/basic_auth_method.go
+++ b/authmethods/basic_auth_method.go
@@ -13,6 +13,7 @@ type BasicAuthMethod struct {
Type string `json:"type" required:"true"`
UUID string `json:"uuid"`
CreatedOn string `json:"created_on"`
+ UpdatedOn string `json:"updated_on,omitempty"`
}
// TempBasicAuthMethod represents the fields that are allowed to be modified
diff --git a/authmethods/headers_auth.go b/authmethods/headers_auth.go
index b924e8f..f7925ce 100644
--- a/authmethods/headers_auth.go
+++ b/authmethods/headers_auth.go
@@ -63,7 +63,7 @@ func (m *HeadersAuthMethod) Update(r io.ReadCloser) (AuthMethod, error) {
var authMBytes []byte
var tempAM TempHeadersAuthMethod
- var updatedAM = NewHeadersAuthMethod()
+ var updatedAM = &HeadersAuthMethod{}
// first fill the temp auth method with the already existing data
// convert the existing auth method to bytes
@@ -110,6 +110,7 @@ func (m *HeadersAuthMethod) Update(r io.ReadCloser) (AuthMethod, error) {
return updatedAM, err
}
+ m.UpdatedOn = utils.ZuluTimeNow()
return updatedAM, err
}
diff --git a/authmethods/headers_auth_test.go b/authmethods/headers_auth_test.go
index edb7a86..9580a6d 100644
--- a/authmethods/headers_auth_test.go
+++ b/authmethods/headers_auth_test.go
@@ -69,6 +69,8 @@ func (suite *HeadersAuthMethodTestSuite) TestUpdate() {
hamUpd1 := HeadersAuthMethod{BasicAuthMethod: amb2, Headers: map[string]string{"x-api-key": "key-2", "Accept": "application/json"}}
r1 := ConvertAuthMethodToReadCloser(&hamUpd1)
a1, err1 := hamUpd1.Update(r1)
+ ca1 := a1.(*HeadersAuthMethod)
+ ham.UpdatedOn = ca1.UpdatedOn
// update fields that aren't supposed to be updated
apkUpd2 := &HeadersAuthMethod{}
diff --git a/bin/argo-api-authn-scripts/ams-create-users-cloud-info.py b/bin/argo-api-authn-scripts/ams-create-users-cloud-info.py
index 6db23a6..053710f 100755
--- a/bin/argo-api-authn-scripts/ams-create-users-cloud-info.py
+++ b/bin/argo-api-authn-scripts/ams-create-users-cloud-info.py
@@ -12,6 +12,7 @@
import ldap
import re
import urllib.parse
+from argo_ams_library import ArgoMessagingService, AmsUser, AmsUserProject, AmsException, AmsServiceException
# set up logging
LOGGER = logging.getLogger("AMS User create script per site")
@@ -97,7 +98,7 @@ def _assign_rdn_to_field(self, rdn_type, rdn_value):
@staticmethod
def _escape_rdn_string(dn_string):
"""
- Method that checks and escapes any possible single slash characters in RDN values
+ Method that checks and escapes any possible single slash characters and commas in RDN values
:param dn_string:
:return: the escaped string
@@ -107,8 +108,7 @@ def _escape_rdn_string(dn_string):
tokens = list(filter(None,re_match_key.split(dn_string)))
escaped_string = "".join(x.replace("/","\/") if not re_match_key.match(x) else x for x in tokens)
- return escaped_string
-
+ return escaped_string.replace(",", "\,")
def _parse_dn_string_ldap_util(self, dn_string):
"""
@@ -301,6 +301,8 @@ def __str__(self):
self._format_rdn_to_string("DC", self.DomainComponent))
return "".join(x for x in printable_string)
+
+
def create_users(config, verify):
# retrieve ams info
@@ -325,6 +327,9 @@ def create_users(config, verify):
# cert key tuple
cert_creds = (config.get("AMS", "cert"), config.get("AMS", "cert_key"))
+ # init the Argo Messaging Service
+ ams = ArgoMessagingService(endpoint=ams_host, token=ams_token, project=ams_project)
+
conf_services = config.get("AMS", "service-types").split(",")
for srv_type in conf_services:
@@ -342,8 +347,8 @@ def create_users(config, verify):
# form the goc db url
goc_db_url = goc_db_url_arch.replace("{{service-type}}", srv_type)
- LOGGER.info("\nAccessing url: " + goc_db_url)
- LOGGER.info("\nStarted the process for service-type: " + srv_type)
+ LOGGER.info("Accessing url: " + goc_db_url)
+ LOGGER.info("Started the process for service-type: " + srv_type)
# grab the xml data from goc db
goc_request = requests.get(url=goc_db_url, cert=cert_creds, verify=False)
@@ -352,6 +357,8 @@ def create_users(config, verify):
# users from goc db that don't have a dn registered
missing_dns = []
+ not_in_production_endpoints = []
+
# build the xml object
root = ET.fromstring(goc_request.text)
# iterate through the xml object's service_endpoints
@@ -368,6 +375,12 @@ def create_users(config, verify):
hostname = service_endpoint.find("HOSTNAME").text.replace(".", "-")
sitename = service_endpoint.find("SITENAME").text.replace(".", "-")
+ # check if the endpoint is in production
+ if service_endpoint.find("IN_PRODUCTION").text != "Y":
+ LOGGER.info("Skipping not in production endpoint: " + hostname)
+ not_in_production_endpoints.append(hostname)
+ continue
+
# try to get the site's contact email
contact_email = ams_email
# check the if we have retrieved this site's contact email before
@@ -395,8 +408,8 @@ def create_users(config, verify):
site_contact_emails[site_name] = contact_email
except Exception as e:
- LOGGER.warning("Skipping endpoint {} under site {}, {}".format(
- hostname, site_name, e))
+ LOGGER.warning("Skipping endpoint {0} under site {1}, {2}".format(
+ hostname, site_name, str(e)))
# Create AMS user
user_binding_name = \
@@ -407,13 +420,14 @@ def create_users(config, verify):
service_dn = RdnSequence(service_dn.text).__str__()
except ValueError as ve:
LOGGER.error(
- "Invalid DN: {}. Exception: {}".
- format(service_dn.text, ve))
+ "Invalid DN: {0}. Exception: {1}".
+ format(service_dn.text, str(ve)))
continue
# check if the given DN already corresponds to a binding
# if the DN is already in use, skip the creation process and only perform the steps where the user
- # is being assigned to the topic's and sub's acl and the respective topic and subscription are being created.
+ # is being assigned to the topic's and sub's acl
+ # and the respective topic and subscription are being created.
# TODO replace ams(service type name) with config value
binding_exists_url = "https://{0}/v1/service-types/ams/hosts/{1}/bindings?key={2}&authID={3}".format(
@@ -431,45 +445,46 @@ def create_users(config, verify):
# else if the Dn isn't in use, go through the full process of creating or updating an existing binding
elif binding_exists_req.status_code == 404:
- project = {'project': ams_project, 'roles': [users_role]}
- usr_create = {'projects': [project], 'email': contact_email}
-
- # create the user
- ams_user_crt_url = 'https://{0}/v1/projects/{1}/members/{2}?key={3}'.format(
- ams_host, ams_project, user_binding_name, ams_token)
- ams_usr_crt_req = requests.post(url=ams_user_crt_url, data=json.dumps(usr_create), verify=verify)
- LOGGER.info(ams_usr_crt_req.text)
-
ams_user_uuid = ""
- # if the response is neither a 200(OK) nor a 409(already exists)
- # then move on to the next user
- if ams_usr_crt_req.status_code != 200 and ams_usr_crt_req.status_code != 409:
- LOGGER.critical("\nUser: " + user_binding_name)
- LOGGER.critical(
- "\nSomething went wrong while creating ams user." +
- "\nBody data: " + str(usr_create) + "\nResponse Body: " +
- ams_usr_crt_req.text)
- continue
-
- if ams_usr_crt_req.status_code == 200:
- ams_user_uuid = ams_usr_crt_req.json()["uuid"]
- # count how many users have been created
+ user_project = AmsUserProject(
+ project=ams_project,
+ roles=[users_role]
+ )
+ user_create_data = AmsUser(
+ projects=[user_project],
+ email=contact_email,
+ name=user_binding_name
+ )
+
+ exists = False
+ try:
+ # create the user
+ created_ams_user = ams.create_user(user=user_create_data, verify=verify)
+ LOGGER.info("Created user: " + created_ams_user.name)
+ ams_user_uuid = created_ams_user.uuid
user_count += 1
+ except AmsException as e:
+ if isinstance(e, AmsServiceException) and e.code == 409:
+ exists = True
+ else:
+ LOGGER.error("User: " + user_binding_name)
+ LOGGER.error(
+ "Something went wrong while creating ams user." +
+ "\nError: " + str(e))
+ continue
# If the user already exists, Get user by username
- if ams_usr_crt_req.status_code == 409:
- proj_member_list_url = "https://{0}/v1/projects/{1}/members/{2}?key={3}".format(ams_host, ams_project, user_binding_name, ams_token)
- ams_usr_get_req = requests.get(url=proj_member_list_url, verify=verify)
-
- # if the user retrieval was ok
- if ams_usr_get_req.status_code == 200:
- LOGGER.info("\nSuccessfully retrieved user {} from ams".format(user_binding_name))
- ams_user_uuid = ams_usr_get_req.json()["uuid"]
- else:
- LOGGER.critical(
- "\nCould not retrieve user {} from ams."
- "\n Response {}".format(user_binding_name, ams_usr_get_req.text))
+ if exists:
+ try:
+ ams_user_uuid = \
+ ams.get_project_member(username=user_binding_name,
+ verify=verify).uuid
+ LOGGER.info("Successfully retrieved user: " + user_binding_name)
+ except AmsException as ae:
+ LOGGER.error(
+ "Could not retrieve user {0} from ams."
+ "\nError: {1}".format(user_binding_name, str(ae)))
continue
# Create the respective AUTH binding
@@ -521,116 +536,101 @@ def create_users(config, verify):
continue
# add the user to the AMS project with corresponding role
- add_user_project_url = "https://{0}/v1/projects/{1}/members/{2}:add?key={3}".format(ams_host,
- ams_project,
- user_binding_name,
- ams_token)
-
- add_user_project_req_body = {
- "project": ams_project,
- "roles": [users_role]
- }
-
- LOGGER.info("Adding user {0} to project {1} . . .".format(user_binding_name, ams_project))
-
- add_user_project_req = requests.post(url=add_user_project_url,
- data=json.dumps(add_user_project_req_body), verify=verify)
-
- if add_user_project_req.status_code != 200 and add_user_project_req.status_code != 409:
- LOGGER.info("Could not add user {0} to project {1}.\nResponse {2}".format(user_binding_name,
- ams_project,
- add_user_project_req.text))
- continue
+ try:
+ ams.add_project_member(username=user_binding_name,
+ roles=[users_role],
+ verify=verify)
+ except AmsException as e:
+ if isinstance(e, AmsServiceException) and e.code == 409:
+ pass
+ else:
+ LOGGER.error("Could not add user {0} to project {1}.\nError: {2}".format(user_binding_name,
+ ams_project,
+ str(e)))
+ continue
- # since both the ams user was created or already existed AND the authn binding was created or already existed
+ # since both the ams user was created or already existed
+ # AND the authn binding was created or already existed
# move to topic and subscription creation
# create new topic
primary_key = service_endpoint. \
find("PRIMARY_KEY").text.replace(' ', '')
topic_name = 'SITE_' + sitename + '_ENDPOINT_' + primary_key
- topic_crt_req = requests.put(
- "https://" + ams_host + "/v1/projects/" + ams_project +
- "/topics/" + topic_name + "?key=" + ams_token, verify=verify)
-
topic_authorized_users = [user_binding_name]
- if topic_crt_req.status_code != 200:
- if topic_crt_req.status_code != 409:
- LOGGER.critical(
- "Something went wrong while creating topic " +
- topic_name + "\nResponse: " + topic_crt_req.text)
- continue
+ topic_exists = False
+
+ try:
+ ams.create_topic(topic=topic_name, verify=verify)
+ except AmsException as e:
+ if isinstance(e, AmsServiceException) and e.code == 409:
+ topic_exists = True
else:
- get_topic_acl_req = requests.get(
- "https://" + ams_host + "/v1/projects/" + ams_project +
- "/topics/" + topic_name + ":acl?key=" + ams_token,
- verify=verify)
- if get_topic_acl_req.status_code == 200:
- acl_users = json.loads(get_topic_acl_req.text)
- topic_authorized_users = topic_authorized_users + acl_users['authorized_users']
- # remove duplicates
- topic_authorized_users = list(set(topic_authorized_users))
-
- # modify the authorized users
- modify_topic_req = requests.post(
- "https://" + ams_host + "/v1/projects/" + ams_project +
- "/topics/" + topic_name + ":modifyAcl?key=" + ams_token,
- data=json.dumps({'authorized_users': topic_authorized_users}),
- verify=verify)
- LOGGER.critical(
- "Modified ACL for topic: {0} with users {1}."
- "Response from AMS {2}".
- format(
- topic_name, str(user_binding_name), modify_topic_req.text))
+ LOGGER.error("Could not create topic: {0}.\nError: {1}".format(topic_name, str(e)))
+ continue
+
+ # modify the topic's acl
+ # check the already existing acl for the topic
+ if topic_exists:
+ try:
+ acl = ams.getacl_topic(topic=topic_name, verify=verify)
+ # remove duplicates
+ topic_authorized_users = list(set(topic_authorized_users + acl["authorized_users"]))
+ except AmsException as ae:
+ LOGGER.error("Couldn't get ACL for topic {0}.\nError: {1}".format(topic_name, str(ae)))
+ continue
+
+ try:
+ ams.modifyacl_topic(topic=topic_name, users=topic_authorized_users, verify=verify)
+ LOGGER.info(
+ "Modified ACL for topic: {0} with users {1}.".format(topic_name, str(topic_authorized_users)))
+ except AmsException as ae:
+ LOGGER.error("Could not modify ACL for topic {0}.\nError: {1}".format(topic_name, str(ae)))
+ continue
# create new sub
primary_key = service_endpoint.find("PRIMARY_KEY").text.replace(' ', '')
sub_name = 'SITE_' + sitename + '_ENDPOINT_' + primary_key
sub_authorized_users = [ams_consumer]
- sub_data = dict()
- sub_data["topic"] = "projects/" + ams_project + "/topics/" + sub_name
- sub_data["ackDeadlineSeconds"] = 100
-
- sub_crt_req = requests.put(
- "https://" + ams_host + "/v1/projects/" + ams_project +
- "/subscriptions/" + sub_name + "?key=" + ams_token, data=json.dumps(sub_data),verify=verify)
-
- if sub_crt_req.status_code != 200 and sub_crt_req.status_code != 409:
- LOGGER.critical(
- "Something went wrong while creating subscription " +
- sub_name + "\nResponse: " + sub_crt_req.text)
-
- if sub_crt_req.status_code == 409:
- get_sub_acl_req = requests.get(
- "https://" + ams_host + "/v1/projects/" + ams_project +
- "/subscriptions/" + sub_name + ":acl?key=" + ams_token,
- verify=verify)
- if get_sub_acl_req.status_code == 200:
- acl_users = json.loads(get_sub_acl_req.text)
- sub_authorized_users = sub_authorized_users + acl_users['authorized_users']
- # remove duplicates
- sub_authorized_users = list(set(sub_authorized_users))
-
- # modify the authorized users
- modify_sub_req = requests.post(
- "https://" + ams_host + "/v1/projects/" + ams_project +
- "/subscriptions/" + sub_name + ":modifyAcl?key=" + ams_token,
- data=json.dumps({'authorized_users': sub_authorized_users}),
- verify=verify)
- LOGGER.critical(
- "Modified ACL for subscription: {0} with users {1}."
- "Response from AMS {2}".
- format(
- sub_name, sub_authorized_users, modify_sub_req.text))
-
- LOGGER.critical("Service Type: " + srv_type)
- LOGGER.critical("Missing DNS: " + str(missing_dns))
- LOGGER.critical("Total Users Created: " + str(user_count))
- LOGGER.critical("Total Bindings Updated: " + str(update_binding_count))
- LOGGER.critical("Updated bingings: " + str(update_bindings_names))
+ sub_exists = False
+
+ try:
+ ams.create_sub(sub=sub_name,
+ topic=topic_name,
+ ackdeadline=100,
+ verify=verify)
+ except AmsException as e:
+ if isinstance(e, AmsServiceException) and e.code == 409:
+ sub_exists = True
+ else:
+ LOGGER.error("Could not create sub: {0}.\nError: {1}".format(sub_name, str(e)))
+ continue
+ # modify the sub's acl
+ # check the already existing acl for the subscription
+ if sub_exists:
+ try:
+ acl = ams.getacl_sub(sub=sub_name, verify=verify)
+ # remove duplicates
+ sub_authorized_users = list(set(sub_authorized_users + acl["authorized_users"]))
+ except AmsException as ae:
+ LOGGER.error("Couldn't get ACL for sub {0}.\nError: {1}".format(sub_name, str(ae)))
+ continue
+
+ try:
+ ams.modifyacl_sub(sub=sub_name, users=sub_authorized_users, verify=verify)
+ LOGGER.info(
+ "Modified ACL for sub: {0} with users {1}.".format(sub_name, str(sub_authorized_users)))
+ except AmsException as ae:
+ LOGGER.error("Could not modify ACL for sub {0}.\nError: {1}".format(sub_name, str(ae)))
+ continue
- LOGGER.critical("-----------------------------------------")
+ LOGGER.info("Service Type: " + srv_type)
+ LOGGER.critical("Missing DNS: " + str(missing_dns))
+ LOGGER.critical("Not in production endpoints: " +str(not_in_production_endpoints))
+ LOGGER.info("Total Users Created: " + str(user_count))
+ LOGGER.info("Total Bindings Updated: " + str(update_binding_count))
+ LOGGER.info("Updated bingings: " + str(update_bindings_names))
def main(args=None):
diff --git a/bin/argo-api-authn-scripts/ams-create-users-gocdb.py b/bin/argo-api-authn-scripts/ams-create-users-gocdb.py
index 78a7ef3..d8c148e 100755
--- a/bin/argo-api-authn-scripts/ams-create-users-gocdb.py
+++ b/bin/argo-api-authn-scripts/ams-create-users-gocdb.py
@@ -12,6 +12,7 @@
import ldap
import re
import urllib.parse
+from argo_ams_library import ArgoMessagingService, AmsUser, AmsUserProject, AmsException, AmsServiceException
# set up logging
LOGGER = logging.getLogger("AMS User create script")
@@ -20,6 +21,7 @@
"emailAddress", "CN", "OU", "O", "postalCode", "street", "L", "ST", "C", "DC"
]
+
class RdnSequence(object):
def __init__(self, rdn_string):
@@ -60,7 +62,6 @@ def _assign_rdn_to_field(self, rdn_type, rdn_value):
Assign an RDN value to the correct field based on its type
"""
-
if rdn_type == "emailAddress":
self.EmailAddress.append(rdn_value)
@@ -94,17 +95,17 @@ def _assign_rdn_to_field(self, rdn_type, rdn_value):
@staticmethod
def _escape_rdn_string(dn_string):
"""
- Method that checks and escapes any possible single slash characters in RDN values
+ Method that checks and escapes any possible single slash characters and commas in RDN values
:param dn_string:
:return: the escaped string
"""
re_match_key = re.compile("(\/\w*=)")
- tokens = list(filter(None,re_match_key.split(dn_string)))
- escaped_string = "".join(x.replace("/","\/") if not re_match_key.match(x) else x for x in tokens)
+ tokens = list(filter(None, re_match_key.split(dn_string)))
+ escaped_string = "".join(x.replace("/", "\/") if not re_match_key.match(x) else x for x in tokens)
- return escaped_string
+ return escaped_string.replace(",", "\,")
def _parse_dn_string_ldap_util(self, dn_string):
"""
@@ -124,7 +125,6 @@ def _parse_dn_string_ldap_util(self, dn_string):
except Exception as e:
raise ValueError(str(e))
-
# A DN string with the value of /DC=org/DC=terena/DC=tcs/C=DE/O=hosts/O=GermanGrid/OU=DESY/CN=host/example.com
# will produce the following rdns list
# ['CN=host/example.com', 'OU=DESY', 'O=GermanGrid', 'O=hosts', 'C=DE', 'DC=tcs', 'DC=terena', 'DC=org']
@@ -300,7 +300,6 @@ def __str__(self):
def create_users(config, verify):
-
# retrieve ams info
ams_host = config.get("AMS", "ams_host")
ams_project = config.get("AMS", "ams_project")
@@ -322,6 +321,9 @@ def create_users(config, verify):
# cert key tuple
cert_creds = (config.get("AMS", "cert"), config.get("AMS", "cert_key"))
+ # init the Argo Messaging Service
+ ams = ArgoMessagingService(endpoint=ams_host, token=ams_token, project=ams_project)
+
# services holds all different services that the users might belong to(which translates to ams topics)
# each service will have a list of users associated with it
services = {}
@@ -336,21 +338,23 @@ def create_users(config, verify):
# form the goc db url
goc_db_url = goc_db_url_arch.replace("{{service-type}}", srv_type)
- LOGGER.info("\nAccessing url: " + goc_db_url)
- LOGGER.info("\nStarted the process for service-type:" + srv_type)
+ LOGGER.info("Accessing url: " + goc_db_url)
+ LOGGER.info("Started the process for service-type: " + srv_type)
# grab the xml data from goc db
- goc_request = requests.get(url=goc_db_url, cert=cert_creds ,verify=False)
+ goc_request = requests.get(url=goc_db_url, cert=cert_creds, verify=False)
LOGGER.info(goc_request.text)
# users from goc db that don't have a dn registered
missing_dns = []
+ not_in_production_endpoints = []
+
# updated bindings count
- update_binding_count= 0
+ update_binding_count = 0
# updated bindings names
- update_bindings_names= []
+ update_bindings_names = []
# srv_type
srv_type = srv_type.replace(".", "-")
@@ -371,6 +375,13 @@ def create_users(config, verify):
# Create AMS user
hostname = service_endpoint.find("HOSTNAME").text.replace(".", "-")
sitename = service_endpoint.find("SITENAME").text.replace(".", "-")
+
+ # check if the endpoint is in production
+ if service_endpoint.find("IN_PRODUCTION").text != "Y":
+ LOGGER.warning("Skipping not in production endpoint: " + hostname)
+ not_in_production_endpoints.append(hostname)
+ continue
+
user_binding_name = service_type + "---" + hostname + "---" + sitename
# try to get the site's contact email
@@ -400,14 +411,14 @@ def create_users(config, verify):
site_contact_emails[site_name] = contact_email
except Exception as e:
- LOGGER.warning("Skipping endpoint {} under site {}, {}".format(
- hostname, site_name, e))
+ LOGGER.warning("Skipping endpoint {0} under site {1}, {2}".format(
+ hostname, site_name, str(e)))
# convert the dn
try:
service_dn = RdnSequence(service_dn.text).__str__()
except ValueError as ve:
- LOGGER.error("Invalid DN: {}. Exception: {}".format(service_dn.text, ve))
+ LOGGER.error("Invalid DN: {0}. Exception: {1}".format(service_dn.text, str(ve)))
continue
# check if the given DN already corresponds to a binding
@@ -430,47 +441,47 @@ def create_users(config, verify):
# else if the Dn isn't in use, go through the full process of creating or updating an existing binding
elif binding_exists_req.status_code == 404:
- project = {'project': ams_project, 'roles': [users_role]}
- usr_create = {'projects': [project], 'email': contact_email}
-
- # create the user
- ams_user_crt_url = 'https://{0}/v1/projects/{1}/members/{2}?key={3}'.format(
- ams_host, ams_project, user_binding_name, ams_token)
- ams_usr_crt_req = requests.post(url=ams_user_crt_url, data=json.dumps(usr_create), verify=verify)
- LOGGER.info(ams_usr_crt_req.text)
-
ams_user_uuid = ""
- # if the response is neither a 200(OK) nor a 409(already exists)
- # then move on to the next user
- if ams_usr_crt_req.status_code != 200 and ams_usr_crt_req.status_code != 409:
- LOGGER.critical("\nUser: " + user_binding_name)
- LOGGER.critical(
- "\nSomething went wrong while creating ams user." +
- "\nBody data: " + str(usr_create) + "\nResponse Body: " +
- ams_usr_crt_req.text)
- continue
-
- if ams_usr_crt_req.status_code == 200:
- ams_user_uuid = ams_usr_crt_req.json()["uuid"]
- # count how many users have been created
+ user_project = AmsUserProject(
+ project=ams_project,
+ roles=[users_role]
+ )
+ user_create_data = AmsUser(
+ projects=[user_project],
+ email=contact_email,
+ name=user_binding_name
+ )
+
+ exists = False
+ try:
+ # create the user
+ created_ams_user = ams.create_user(user=user_create_data, verify=verify)
+ LOGGER.info("Created user: " + created_ams_user.name)
+ ams_user_uuid = created_ams_user.uuid
user_count += 1
-
- # If the user already exists, Get user by username
- if ams_usr_crt_req.status_code == 409:
- proj_member_list_url = "https://{0}/v1/projects/{1}/members/{2}?key={3}".format(ams_host, ams_project, user_binding_name, ams_token)
- ams_usr_get_req = requests.get(url=proj_member_list_url, verify=verify)
-
- # if the user retrieval was ok
- if ams_usr_get_req.status_code == 200:
- LOGGER.info("\nSuccessfully retrieved user {} from ams".format(user_binding_name))
- ams_user_uuid = ams_usr_get_req.json()["uuid"]
+ except AmsException as e:
+ if isinstance(e, AmsServiceException) and e.code == 409:
+ exists = True
else:
- LOGGER.critical(
- "\nCould not retrieve user {} from ams."
- "\n Response {}".format(user_binding_name, ams_usr_get_req.text))
+ LOGGER.error("User: " + user_binding_name)
+ LOGGER.error(
+ "Something went wrong while creating ams user." +
+ "\nError: " + str(e))
continue
+ # If the user already exists, Get user by username
+ if exists:
+ try:
+ ams_user_uuid = \
+ ams.get_project_member(username=user_binding_name,
+ verify=verify).uuid
+ LOGGER.info("Successfully retrieved user: " + user_binding_name)
+ except AmsException as ae:
+ LOGGER.error(
+ "Could not retrieve user {0} from ams."
+ "\nError: {1}".format(user_binding_name, str(ae)))
+ continue
# Create the respective AUTH binding
bd_data = {
@@ -481,33 +492,40 @@ def create_users(config, verify):
"auth_type": "x509"
}
- create_binding_url = "https://{0}/v1/bindings/{1}?key={2}".format(authn_host, user_binding_name, authn_token)
+ create_binding_url = "https://{0}/v1/bindings/{1}?key={2}".format(authn_host, user_binding_name,
+ authn_token)
authn_binding_crt_req = requests.post(url=create_binding_url, data=json.dumps(bd_data), verify=verify)
LOGGER.info(authn_binding_crt_req.text)
if authn_binding_crt_req.status_code != 201 and authn_binding_crt_req.status_code != 409:
- LOGGER.critical("Something went wrong while creating a binding.\nBody data: " + str(bd_data) + "\nResponse: " + authn_binding_crt_req.text)
+ LOGGER.critical("Something went wrong while creating a binding.\nBody data: " + str(
+ bd_data) + "\nResponse: " + authn_binding_crt_req.text)
continue
# if the binding already exists, check for an updated DN from gocdb
if authn_binding_crt_req.status_code == 409:
- retrieve_binding_url = "https://{0}/v1/bindings/{1}?key={2}".format(authn_host, user_binding_name, authn_token)
+ retrieve_binding_url = "https://{0}/v1/bindings/{1}?key={2}".format(authn_host, user_binding_name,
+ authn_token)
authn_ret_bind_req = requests.get(url=retrieve_binding_url, verify=verify)
# if the binding retrieval was ok
if authn_ret_bind_req.status_code == 200:
- LOGGER.info("\nSuccessfully retrieved binding {} from authn. Checking for DN update.".format(user_binding_name))
+ LOGGER.info("Successfully retrieved binding {0} from authn.Checking for DN update.".format(
+ user_binding_name))
binding = authn_ret_bind_req.json()
# check if the dn has changed
if binding["auth_identifier"] != service_dn:
# update the respective binding with the new dn
- bind_upd_req_url = "https://{0}/v1/bindings/{1}?key={2}".format(authn_host, user_binding_name, authn_token)
+ bind_upd_req_url = "https://{0}/v1/bindings/{1}?key={2}".format(authn_host,
+ user_binding_name,
+ authn_token)
upd_bd_data = {
"auth_identifier": service_dn
}
- authn_bind_upd_req = requests.put(url=bind_upd_req_url, data=json.dumps(upd_bd_data), verify=verify)
+ authn_bind_upd_req = requests.put(url=bind_upd_req_url, data=json.dumps(upd_bd_data),
+ verify=verify)
LOGGER.info(authn_bind_upd_req.text)
if authn_bind_upd_req.status_code == 200:
update_binding_count += 1
@@ -515,70 +533,58 @@ def create_users(config, verify):
else:
LOGGER.critical(
- "\nCould not retrieve binding {} from authn."
- "\n Response {}".format(user_binding_name, authn_ret_bind_req.text))
+ "\nCould not retrieve binding {0} from authn."
+ "\nResponse {1}".format(user_binding_name, authn_ret_bind_req.text))
continue
-
# add the user to the AMS project with corresponding role
- add_user_project_url = "https://{0}/v1/projects/{1}/members/{2}:add?key={3}".format(ams_host,
- ams_project,
- user_binding_name,
- ams_token)
-
- add_user_project_req_body = {
- "project": ams_project,
- "roles": [users_role]
- }
-
- LOGGER.info("Adding user {0} to project {1} . . .".format(user_binding_name, ams_project))
-
- add_user_project_req = requests.post(url=add_user_project_url,
- data=json.dumps(add_user_project_req_body), verify=verify)
-
- if add_user_project_req.status_code != 200 and add_user_project_req.status_code != 409 :
- LOGGER.info("Could not add user {0} to project {1}.\nResponse {2}".format(user_binding_name,
- ams_project,
- add_user_project_req.text))
- continue
+ try:
+ ams.add_project_member(username=user_binding_name,
+ roles=[users_role],
+ verify=verify)
+ except AmsException as e:
+ if isinstance(e, AmsServiceException) and e.code == 409:
+ pass
+ else:
+ LOGGER.error("Could not add user {0} to project {1}.\nError: {2}".format(user_binding_name,
+ ams_project,
+ str(e)))
+ continue
# if both the user and binding have been created, assign the user to the acl of the topic
services[service_type].append(user_binding_name)
LOGGER.info("Marked user {0} to be added to the {1} topic under the {2} project".format(
user_binding_name, service_type, ams_project))
-
# modify the acl for each topic , to add all associated users
authorized_users = services[srv_type]
if len(authorized_users) != 0:
-
- get_topic_acl_req = requests.get("https://"+ams_host+"/v1/projects/"+ams_project+"/topics/"+srv_type+":acl?key="+ams_token, verify=verify)
-
- if get_topic_acl_req.status_code == 200:
- acl_users = json.loads(get_topic_acl_req.text)
- authorized_users = authorized_users + acl_users["authorized_users"]
+ try:
+ acl = ams.getacl_topic(topic=srv_type, verify=verify)
# remove duplicates
- authorized_users = list(set(authorized_users))
- modify_topic_acl_req = requests.post("https://"+ams_host+"/v1/projects/"+ams_project+"/topics/"+srv_type+":modifyAcl?key="+ams_token, data=json.dumps({'authorized_users': authorized_users}), verify=verify)
- LOGGER.critical("Modified ACL for topic: {} with users {}. Response from AMS {}".format(srv_type, str(authorized_users), modify_topic_acl_req.text))
- else:
- LOGGER.critical("Couldn't get ACL for topic {}. Response from AMS {}".format(srv_type, get_topic_acl_req.text))
+ authorized_users = list(set(authorized_users + acl["authorized_users"]))
+ try:
+ ams.modifyacl_topic(topic=srv_type, users=authorized_users, verify=verify)
+ LOGGER.info("Modified ACL for topic: {0} with users {1}.".format(srv_type, str(authorized_users)))
+ except AmsException as ae:
+ LOGGER.error("Could not modify ACL for topic {0}.\nError: {1}".format(srv_type, str(ae)))
+ except AmsException as ae:
+ LOGGER.error("Couldn't get ACL for topic {0}.\nError: {1}".format(srv_type, str(ae)))
- LOGGER.critical("Service Type: " + srv_type)
+ LOGGER.info("Service Type: " + srv_type)
LOGGER.critical("Missing DNS: " + str(missing_dns))
- LOGGER.critical("Total Users Created: " + str(user_count))
-
- LOGGER.critical("Total Bindings Updated: " + str(update_binding_count))
-
- LOGGER.critical("Updated bindings: " + str(update_bindings_names))
+ LOGGER.critical("Not in production endpoints: " + str(not_in_production_endpoints))
- LOGGER.critical("-----------------------------------------")
+ LOGGER.info("Total Users Created: " + str(user_count))
+ LOGGER.info("Total Bindings Updated: " + str(update_binding_count))
+
+ LOGGER.info("Updated bindings: " + str(update_bindings_names))
-def main(args=None):
+def main(args=None):
# set up the config parser
config = configparser.ConfigParser()
@@ -609,11 +615,11 @@ def main(args=None):
if __name__ == "__main__":
-
- parser = argparse.ArgumentParser(description="Create ams users and their respective bindings using data imported from goc db")
+ parser = argparse.ArgumentParser(
+ description="Create ams users and their respective bindings using data imported from goc db")
parser.add_argument(
"-c", "--ConfigPath", type=str, help="Path for the config file")
parser.add_argument(
- "-verify", "--Verify", help="SSL verification for requests", action="store_true")
+ "-verify", "--Verify", help="SSL verification for requests", action="store_true")
- sys.exit(main(parser.parse_args()))
\ No newline at end of file
+ sys.exit(main(parser.parse_args()))
diff --git a/bin/requirements.txt b/bin/requirements.txt
index dae2ebe..faf6bdc 100644
--- a/bin/requirements.txt
+++ b/bin/requirements.txt
@@ -1,3 +1,4 @@
-defusedxml==0.5.0
-requests==2.20
+defusedxml==0.7.1
python-ldap==3.4.0
+argo-ams-library==0.5.9
+requests
diff --git a/bindings/binding.go b/bindings/binding.go
index 03291ba..582d9da 100644
--- a/bindings/binding.go
+++ b/bindings/binding.go
@@ -17,6 +17,7 @@ type Binding struct {
UniqueKey string `json:"unique_key" required:"true"`
AuthType string `json:"auth_type" required:"true"`
CreatedOn string `json:"created_on,omitempty"`
+ UpdatedOn string `json:"updated_on,omitempty"`
LastAuth string `json:"last_auth,omitempty"`
}
@@ -305,6 +306,8 @@ func UpdateBinding(original Binding, tempBind TempUpdateBinding, store stores.St
return Binding{}, err
}
+ updated.UpdatedOn = utils.ZuluTimeNow()
+
// convert the updated binding to a QBinding
if err := utils.CopyFields(updated, &qUpdatedBinding); err != nil {
err = utils.APIGenericInternalError(err.Error())
diff --git a/conf/argo-api-authn-config.template b/conf/argo-api-authn-config.template
index 0c38402..f121389 100644
--- a/conf/argo-api-authn-config.template
+++ b/conf/argo-api-authn-config.template
@@ -7,12 +7,12 @@
"certificate_key":"/etc/pki/tls/private/localhost.key",
"service_token": "agelos",
"supported_auth_types": ["x509", "oidc"],
- "supported_auth_methods": ["api-key", "x-api-token"],
+ "supported_auth_methods": ["api-key", "headers"],
"supported_service_types": ["ams", "web-api", "custom"],
"verify_ssl": false,
"trust_unknown_cas": true,
"verify_certificate": false,
- "service_types_paths": {"ams": "/v1/users:byUUID/{{identifier}}?key={{access_key}}"},
+ "service_types_paths": {"ams": "/v1/users:byUUID/{{identifier}}"},
"service_types_retrieval_fields": {"ams": "token"},
"syslog_enabled": false,
"client_cert_host_verification" : false
diff --git a/config.json b/config.json
index df4bfd8..ffe2384 100644
--- a/config.json
+++ b/config.json
@@ -13,7 +13,7 @@
"trust_unknown_cas": false,
"verify_certificate": true,
"service_types_paths": {
- "ams": "/v1/users:byUUID/{{identifier}}?key={{access_key}}",
+ "ams": "/v1/users:byUUID/{{identifier}}}",
"web-api": "/api/v2/admin/users:byID/{{identifier}}?export=flat"
},
"service_types_retrieval_fields": {
diff --git a/config/config_test.go b/config/config_test.go
index 675a483..62ab326 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -35,7 +35,7 @@ func (suite *ConfigTestSuite) TestConfigSetUp() {
TrustUnknownCAs: false,
VerifyCertificate: true,
ServiceTypesPaths: map[string]string{
- "ams": "/v1/users:byUUID/{{identifier}}?key={{access_key}}",
+ "ams": "/v1/users:byUUID/{{identifier}}",
"web-api": "/api/v2/admin/users:byID/{{identifier}}?export=flat",
},
ServiceTypesRetrievalFields: map[string]string{
diff --git a/config/configuration-test-files/test-conf.json b/config/configuration-test-files/test-conf.json
index d7f02ff..6d7018c 100644
--- a/config/configuration-test-files/test-conf.json
+++ b/config/configuration-test-files/test-conf.json
@@ -13,7 +13,7 @@
"trust_unknown_cas": false,
"verify_certificate": true,
"service_types_paths": {
- "ams": "/v1/users:byUUID/{{identifier}}?key={{access_key}}",
+ "ams": "/v1/users:byUUID/{{identifier}}",
"web-api": "/api/v2/admin/users:byID/{{identifier}}?export=flat"
},
"service_types_retrieval_fields": {
diff --git a/docs/swagger.yml b/docs/swagger.yml
index 4548ddc..8011852 100644
--- a/docs/swagger.yml
+++ b/docs/swagger.yml
@@ -683,6 +683,10 @@ definitions:
description: the type of authentication that this binding represets(e.g. x509)
created_on:
type: string
+ description: when the binding was created
+ updated_on:
+ type: string
+ description: when the binding was updated
last_auth:
type: string
@@ -722,8 +726,10 @@ definitions:
description: service type's type, either AMS or web-api
created_on:
type: string
- enum: [ams, web-api]
description: datetime of creation
+ updated_on:
+ type: string
+ description: when the servcie type was updated
AuthMethods:
type: object
@@ -763,6 +769,9 @@ definitions:
created_on:
type: string
description: when the auth method was created
+ updated_on:
+ type: string
+ description: when the auth method was updated
TokenResponse:
diff --git a/docs/v1/docs/api_authmethods.md b/docs/v1/docs/api_authmethods.md
index 8fdcfbe..7e162de 100644
--- a/docs/v1/docs/api_authmethods.md
+++ b/docs/v1/docs/api_authmethods.md
@@ -80,7 +80,10 @@ Success Response
```
{
- "access_key": "key1",
+ "headers": {
+ "header-1": "value-1",
+ "header-2": "value-2"
+ },
"host": "127.0.0.1",
"service_uuid": "da22b2d4-ba6c-43ca-b28d-400sd0a5d83e",
"port": 9000,
@@ -121,7 +124,8 @@ If the request is successful, the response contains information for the requeste
"port": 9000,
"type": "api-key",
"uuid": "da22b2d4-8ip0-43ca-b28d-500sd0a5d876e",
- "created_on": "2018-05-05T18:04:05Z"
+ "created_on": "2018-05-05T18:04:05Z",
+ "updated_on": "2021-05-05T18:04:05Z"
}
```
Please refer to section [Errors](api_errors.md) to see all possible Errors
@@ -157,7 +161,8 @@ If the request is successful, the response contains information for all the auth
"port": 9000,
"type": "api-key",
"uuid": "da22b2d4-8ip0-43ca-b28d-500sd0a5d876e",
- "created_on": "2018-05-05T18:04:05Z"
+ "created_on": "2018-05-05T18:04:05Z",
+ "updated_on": "2021-05-05T18:04:05Z"
},
{
"access_key": "key1",
@@ -166,7 +171,8 @@ If the request is successful, the response contains information for all the auth
"port": 9000,
"type": "api-key",
"uuid": "da22b2d4-9kl2-43ca-b28d-500sd0a5d876e",
- "created_on": "2018-05-05T18:04:05Z"
+ "created_on": "2018-05-05T18:04:05Z",
+ "updated_on": "2021-05-05T18:04:05Z"
}
]
}
@@ -214,7 +220,8 @@ Success Response
"port": 8080,
"type": "api-key",
"uuid": "da22b2d4-8ip0-43ca-b28d-500sd0a5d876e",
- "created_on": "2018-05-05T18:04:05Z"
+ "created_on": "2018-05-05T18:04:05Z",
+ "updated_on": "2021-05-05T18:04:05Z"
}
```
diff --git a/docs/v1/docs/api_bindings.md b/docs/v1/docs/api_bindings.md
index d95727c..4884ead 100644
--- a/docs/v1/docs/api_bindings.md
+++ b/docs/v1/docs/api_bindings.md
@@ -99,6 +99,7 @@ If the request is successful, the response contains all the bindings in the serv
"unique_key": "key",
"auth_type": "x509",
"created_on": "2018-05-23T09:25:25Z",
+ "updated_on": "2021-05-05T18:04:05Z"
"last_auth": "2018-05-23T09:25:25Z"
},
{
@@ -161,6 +162,7 @@ If the request is successful, the response contains all the bindings under the g
"unique_key": "key",
"auth_type": "x509",
"created_on": "2018-05-23T09:25:43Z",
+ "updated_on": "2021-05-05T18:04:05Z"
"last_auth": "2018-05-23T09:25:25Z"
}
]
@@ -287,7 +289,8 @@ If the request is successful, the response contains the updated binding.
"auth_identifier": "host1",
"unique_key": "key",
"auth_type": "x509",
- "created_on": "2018-05-24T09:58:17Z"
+ "created_on": "2018-05-24T09:58:17Z",
+ "updated_on": "2021-05-05T18:04:05Z"
}
```
diff --git a/docs/v1/docs/api_service_types.md b/docs/v1/docs/api_service_types.md
index acb5276..c1a872e 100644
--- a/docs/v1/docs/api_service_types.md
+++ b/docs/v1/docs/api_service_types.md
@@ -105,7 +105,8 @@ GET/v1/service-types
"auth_method": "api-key",
"uuid": "da22b2d4-ba6c-43ca-b28d-400sd0a5d83e",
"type": "ams",
- "created_on": "2018-05-13T21:52:58Z"
+ "created_on": "2018-05-13T21:52:58Z",
+ "updated_on": "2021-05-05T18:04:05Z"
}
]
}
@@ -137,7 +138,8 @@ If the request is successful, the response contains information for the requeste
"auth_method": "api-key",
"uuid": "da22b2d4-ba6c-43ca-b28d-400cd0a5d83e",
"type": "ams",
- "created_on": "2018-05-05T18:04:05Z"
+ "created_on": "2018-05-05T18:04:05Z",
+ "updated_on": "2021-05-05T18:04:05Z"
}
```
@@ -180,7 +182,8 @@ If the request is successful, the response contains the updated service type.
"auth_method": "api-key",
"uuid": "da22b2d4-ba6c-43ca-b28d-400cd0a5d83e",
"type": "ams",
- "created_on": "2018-05-05T18:04:05Z"
+ "created_on": "2018-05-05T18:04:05Z",
+ "updated_on": "2021-05-05T18:04:05Z"
}
```
diff --git a/handlers/authmethods_handlers_test.go b/handlers/authmethods_handlers_test.go
index 5f263c7..2f65315 100644
--- a/handlers/authmethods_handlers_test.go
+++ b/handlers/authmethods_handlers_test.go
@@ -6,12 +6,15 @@ import (
"github.com/ARGOeu/argo-api-authn/authmethods"
"github.com/ARGOeu/argo-api-authn/config"
"github.com/ARGOeu/argo-api-authn/stores"
+ "github.com/ARGOeu/argo-api-authn/utils"
"github.com/gorilla/mux"
LOGGER "github.com/sirupsen/logrus"
"github.com/stretchr/testify/suite"
"net/http"
"net/http/httptest"
+ "strings"
"testing"
+ "time"
)
type AuthMethodsHandlersTestSuite struct {
@@ -793,6 +796,7 @@ func (suite *AuthMethodsHandlersTestSuite) TestAuthMethodUpdateOne() {
"type": "api-key",
"uuid": "am_uuid_1",
"created_on": "",
+ "updated_on": "{{UPDATED_ON}}",
"access_key": "key1"
}`
@@ -811,6 +815,12 @@ func (suite *AuthMethodsHandlersTestSuite) TestAuthMethodUpdateOne() {
w := httptest.NewRecorder()
router.HandleFunc("/service-types/{service-type}/hosts/{host}/authm", WrapConfig(AuthMethodUpdateOne, mockstore, cfg))
router.ServeHTTP(w, req)
+
+ amU, _ := mockstore.QueryApiKeyAuthMethods("uuid1", "host1")
+ expRespJSON = strings.Replace(expRespJSON, "{{UPDATED_ON}}", amU[0].UpdatedOn, 1)
+ // make sure the updated time is before now
+ updatedTime, _ := time.Parse(utils.ZULU_FORM, amU[0].UpdatedOn)
+ suite.True(updatedTime.Before(time.Now().UTC()))
suite.Equal(200, w.Code)
suite.Equal(expRespJSON, w.Body.String())
}
@@ -831,6 +841,7 @@ func (suite *AuthMethodsHandlersTestSuite) TestAuthMethodUpdateOneIllegalFields(
"type": "api-key",
"uuid": "am_uuid_1",
"created_on": "",
+ "updated_on": "{{UPDATED_ON}}",
"access_key": "access_key"
}`
@@ -849,6 +860,12 @@ func (suite *AuthMethodsHandlersTestSuite) TestAuthMethodUpdateOneIllegalFields(
w := httptest.NewRecorder()
router.HandleFunc("/service-types/{service-type}/hosts/{host}/authm", WrapConfig(AuthMethodUpdateOne, mockstore, cfg))
router.ServeHTTP(w, req)
+
+ amU, _ := mockstore.QueryApiKeyAuthMethods("uuid1", "host1")
+ expRespJSON = strings.Replace(expRespJSON, "{{UPDATED_ON}}", amU[0].UpdatedOn, 1)
+ // make sure the updated time is before now
+ updatedTime, _ := time.Parse(utils.ZULU_FORM, amU[0].UpdatedOn)
+ suite.True(updatedTime.Before(time.Now().UTC()))
suite.Equal(200, w.Code)
suite.Equal(expRespJSON, w.Body.String())
}
diff --git a/handlers/binding_handlers_test.go b/handlers/binding_handlers_test.go
index d52bac9..86fab93 100644
--- a/handlers/binding_handlers_test.go
+++ b/handlers/binding_handlers_test.go
@@ -3,10 +3,13 @@ package handlers
import (
"bytes"
"github.com/ARGOeu/argo-api-authn/stores"
+ "github.com/ARGOeu/argo-api-authn/utils"
LOGGER "github.com/sirupsen/logrus"
"github.com/stretchr/testify/suite"
"net/http"
+ "strings"
"testing"
+ "time"
"encoding/json"
"github.com/ARGOeu/argo-api-authn/bindings"
@@ -865,7 +868,8 @@ func (suite *BindingHandlersSuite) TestBindingUpdate() {
"auth_identifier": "test_dn_1",
"unique_key": "unique_key_1",
"auth_type": "x509",
- "created_on": "2018-05-05T15:04:05Z"
+ "created_on": "2018-05-05T15:04:05Z",
+ "updated_on": "{{UPDATED_ON}}"
}`
req, err := http.NewRequest("PUT", "http://localhost:8080/bindings/b1", bytes.NewBuffer([]byte(postJSON)))
if err != nil {
@@ -882,6 +886,13 @@ func (suite *BindingHandlersSuite) TestBindingUpdate() {
w := httptest.NewRecorder()
router.HandleFunc("/bindings/{name}", WrapConfig(BindingUpdate, mockstore, cfg))
router.ServeHTTP(w, req)
+
+ qB, _ := mockstore.QueryBindingsByUUIDAndName("b_uuid1", "updated_name")
+ expRespJSON = strings.Replace(expRespJSON, "{{UPDATED_ON}}", qB[0].UpdatedOn, 1)
+ // make sure the updated time is before now
+ updatedTime, _ := time.Parse(utils.ZULU_FORM, qB[0].UpdatedOn)
+ suite.True(updatedTime.Before(time.Now().UTC()))
+
suite.Equal(200, w.Code)
suite.Equal(expRespJSON, w.Body.String())
}
diff --git a/handlers/service_type_handlers_test.go b/handlers/service_type_handlers_test.go
index a2cfc0c..71cd343 100644
--- a/handlers/service_type_handlers_test.go
+++ b/handlers/service_type_handlers_test.go
@@ -2,10 +2,13 @@ package handlers
import (
"bytes"
+ "github.com/ARGOeu/argo-api-authn/utils"
LOGGER "github.com/sirupsen/logrus"
"github.com/stretchr/testify/suite"
"net/http"
+ "strings"
"testing"
+ "time"
"encoding/json"
"github.com/ARGOeu/argo-api-authn/config"
@@ -676,6 +679,7 @@ func (suite *BindingHandlersSuite) TestServiceTypeUpdate() {
"auth_method": "api-key",
"uuid": "uuid1",
"created_on": "2018-05-05T18:04:05Z",
+ "updated_on": "{{UPDATED_ON}}",
"type": "ams"
}`
req, err := http.NewRequest("PUT", "http://localhost:8080/service-types/s1", bytes.NewBuffer([]byte(postJSON)))
@@ -693,6 +697,12 @@ func (suite *BindingHandlersSuite) TestServiceTypeUpdate() {
w := httptest.NewRecorder()
router.HandleFunc("/service-types/{service-type}", WrapConfig(ServiceTypeUpdate, mockstore, cfg))
router.ServeHTTP(w, req)
+
+ qSt, _ := mockstore.QueryServiceTypes("updated_name")
+ expRespJSON = strings.Replace(expRespJSON, "{{UPDATED_ON}}", qSt[0].UpdatedOn, 1)
+ // make sure the updated time is before now
+ updatedTime, _ := time.Parse(utils.ZULU_FORM, qSt[0].UpdatedOn)
+ suite.True(updatedTime.Before(time.Now().UTC()))
suite.Equal(200, w.Code)
suite.Equal(expRespJSON, w.Body.String())
}
diff --git a/main.go b/main.go
index 69b53f9..e00058f 100644
--- a/main.go
+++ b/main.go
@@ -47,7 +47,7 @@ func main() {
// configure the TLS config for the server
tlsConfig := &tls.Config{
- MinVersion: tls.VersionTLS10,
+ MinVersion: tls.VersionTLS12,
ClientAuth: cfg.ClientAuthPolicy(),
ClientCAs: auth.LoadCAs(cfg.CertificateAuthorities),
}
diff --git a/postman/authn_ci-cd_tests.postman_collection.json b/postman/authn_ci-cd_tests.postman_collection.json
index 4f29c7e..9923293 100644
--- a/postman/authn_ci-cd_tests.postman_collection.json
+++ b/postman/authn_ci-cd_tests.postman_collection.json
@@ -66,10 +66,10 @@
{
"listen": "test",
"script": {
- "id": "c95d2c5c-937d-4df0-873d-f6fd9e35de9b",
+ "id": "edf1b517-d398-4834-8de2-50bf840c2383",
"type": "text/javascript",
"exec": [
- "pm.test(\"Check that the Servie-type was successfully created\", function(){",
+ "pm.test(\"Check that the Service-type was successfully created\", function(){",
" pm.response.to.have.status(201) ",
"});",
"",
@@ -89,7 +89,7 @@
],
"body": {
"mode": "raw",
- "raw": "{\n\t\"name\": \"ams-devel-cicd\",\n\t\"hosts\": [\"{{ams-host}}\"],\n\t\"auth_types\": [\"x509\"],\n\t\"auth_method\": \"api-key\",\n\t\"type\": \"ams\"\n}"
+ "raw": "{\n\t\"name\": \"ams-devel-cicd\",\n\t\"hosts\": [\"{{ams-host}}\"],\n\t\"auth_types\": [\"x509\"],\n\t\"auth_method\": \"headers\",\n\t\"type\": \"ams\"\n}"
},
"url": {
"raw": "https://{{authn-host}}/v1/service-types?key={{authn-token}}",
@@ -137,7 +137,7 @@
],
"body": {
"mode": "raw",
- "raw": "{\n\t\"port\": 443,\n\t\"host\": \"{{ams-host}}\",\n\t\"access_key\": \"{{ams-token}}\"\n}"
+ "raw": "{\n\t\"port\": 443,\n\t\"host\": \"{{ams-host}}\",\n\t\"headers\": {\n\t\t\"x-api-key\": \"{{ams-token}}\"\n\t}\n}"
},
"url": {
"raw": "https://{{authn-host}}/v1/service-types/ams-devel-cicd/authm?key={{authn-token}}",
@@ -187,7 +187,7 @@
],
"body": {
"mode": "raw",
- "raw": "{\n\t\"service_uuid\": \"{{st-uuid}}\",\n\t\"host\": \"{{ams-host}}\",\n\t\"auth_identifier\": \"CN=jenkins.einfra.grnet.gr,OU=E-Infrastructures Department,O=National Infrastructures for Research and Technology (GRNET),L=Athens,C=GR\",\n\t\"unique_key\": \"3530bde2-a8bc-417b-9f8e-c36dedeedafb\",\n\t\"auth_type\": \"x509\"\n}\n"
+ "raw": "{\n\t\"service_uuid\": \"{{st-uuid}}\",\n\t\"host\": \"{{ams-host}}\",\n\t\"auth_identifier\": \"CN=*.einfra.grnet.gr,OU=GRNET,O=National Infrastructures for Research and Technology,ST=Attikí,C=GR\",\n\t\"unique_key\": \"3530bde2-a8bc-417b-9f8e-c36dedeedafb\",\n\t\"auth_type\": \"x509\"\n}\n"
},
"url": {
"raw": "https://{{authn-host}}/v1/bindings/authn-cicd?key={{authn-token}}",
diff --git a/routing/routing.go b/routing/routing.go
index 8d455ee..c63ed62 100644
--- a/routing/routing.go
+++ b/routing/routing.go
@@ -69,7 +69,7 @@ func NewRouting(routes []APIRoute, store stores.Store, config *config.Config) *A
}
var ApiRoutes = []APIRoute{
- {"serviceTypes:create", "POST", "/service-types", handlers.ServiceTypeCreate, true},
+ {"serviceTypes:Create", "POST", "/service-types", handlers.ServiceTypeCreate, true},
{"serviceTypes:ListOne", "GET", "/service-types/{service-type}", handlers.ServiceTypesListOne, true},
{"serviceTypes:DeleteOne", "DELETE", "/service-types/{service-type}", handlers.ServiceTypeDeleteOne, true},
{"serviceTypes:ListOne", "PUT", "/service-types/{service-type}", handlers.ServiceTypeUpdate, true},
@@ -77,13 +77,13 @@ var ApiRoutes = []APIRoute{
{"authMethod:Create", "POST", "/service-types/{service-type}/authm", handlers.AuthMethodCreate, true},
{"authMethod:ListOne", "GET", "/service-types/{service-type}/hosts/{host}/authm", handlers.AuthMethodListOne, true},
{"authMethod:Delete", "DELETE", "/service-types/{service-type}/hosts/{host}/authm", handlers.AuthMethodDeleteOne, true},
- {"authMethod:Delete", "PUT", "/service-types/{service-type}/hosts/{host}/authm", handlers.AuthMethodUpdateOne, true},
+ {"authMethod:Update", "PUT", "/service-types/{service-type}/hosts/{host}/authm", handlers.AuthMethodUpdateOne, true},
{"bindings:ListAllByServiceTypeAndHost", "GET", "/service-types/{service-type}/hosts/{host}/bindings", handlers.BindingListAllByServiceTypeAndHost, true},
{"authMethod:ListAll", "GET", "/authm", handlers.AuthMethodListAll, true},
- {"bindings:create", "POST", "/bindings/{name}", handlers.BindingCreate, true},
+ {"bindings:Create", "POST", "/bindings/{name}", handlers.BindingCreate, true},
{"bindings:ListAll", "GET", "/bindings", handlers.BindingListAll, true},
- {"bindings:update", "PUT", "/bindings/{name}", handlers.BindingUpdate, true},
+ {"bindings:Update", "PUT", "/bindings/{name}", handlers.BindingUpdate, true},
{"bindings:ListOneByName", "GET", "/bindings/{name}", handlers.BindingListOneByName, true},
- {"bindings:delete", "DELETE", "/bindings/{name}", handlers.BindingDelete, true},
- {"auth:dn", "GET", "/service-types/{service-type}/hosts/{host}:authx509", handlers.AuthViaCert, false},
+ {"bindings:Delete", "DELETE", "/bindings/{name}", handlers.BindingDelete, true},
+ {"auth:Map", "GET", "/service-types/{service-type}/hosts/{host}:authx509", handlers.AuthViaCert, false},
}
diff --git a/servicetypes/service_type.go b/servicetypes/service_type.go
index 20b239a..b653673 100644
--- a/servicetypes/service_type.go
+++ b/servicetypes/service_type.go
@@ -15,6 +15,7 @@ type ServiceType struct {
AuthMethod string `json:"auth_method" required:"true"`
UUID string `json:"uuid"`
CreatedOn string `json:"created_on"`
+ UpdatedOn string `json:"updated_on,omitempty"`
Type string `json:"type" required:"true"`
}
@@ -320,6 +321,8 @@ func UpdateServiceType(original ServiceType, tempServiceType TempServiceType, st
}
}
+ updated.UpdatedOn = utils.ZuluTimeNow()
+
// convert the original service type to a QServiceType
if err := utils.CopyFields(original, &qOriginalSt); err != nil {
err = utils.APIGenericInternalError(err.Error())
diff --git a/servicetypes/service_type_test.go b/servicetypes/service_type_test.go
index 208a52a..531688e 100644
--- a/servicetypes/service_type_test.go
+++ b/servicetypes/service_type_test.go
@@ -20,55 +20,55 @@ func (suite *ServiceTestSuite) TestCreateServiceType() {
_ = cfg.ConfigSetUp("../config/configuration-test-files/test-conf.json")
// test the normal case with type ams
- s1 := ServiceType{"sCr", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "ams"}
+ s1 := ServiceType{"sCr", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "", "ams"}
_, err := CreateServiceType(s1, mockstore, *cfg)
res1, _ := mockstore.QueryServiceTypes("sCr")
// test the normal case with type web-api
- sWb := ServiceType{"sCr_wb", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "web-api"}
+ sWb := ServiceType{"sCr_wb", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "", "web-api"}
_, errWb := CreateServiceType(sWb, mockstore, *cfg)
res2, _ := mockstore.QueryServiceTypes("sCr_wb")
// test the normal case with type custom
- sCustom := ServiceType{"sCr_custom", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "token", "custom"}
+ sCustom := ServiceType{"sCr_custom", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "token", "", "custom"}
_, errCustom := CreateServiceType(sCustom, mockstore, *cfg)
res3, _ := mockstore.QueryServiceTypes("sCr_custom")
// test the case where the name already exists
- s2 := ServiceType{"s1", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "some_uuid", "", "ams"}
+ s2 := ServiceType{"s1", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "some_uuid", "", "", "ams"}
_, err2 := CreateServiceType(s2, mockstore, *cfg)
// test the case of unsupported auth type
- s3 := ServiceType{"sCr", []string{"host1", "host2"}, []string{"unsup_type", "oidc"}, "api-key", "some_uuid", "", "ams"}
+ s3 := ServiceType{"sCr", []string{"host1", "host2"}, []string{"unsup_type", "oidc"}, "api-key", "some_uuid", "", "", "ams"}
_, err3 := CreateServiceType(s3, mockstore, *cfg)
// test the case of empty auth type list
- s4 := ServiceType{"sCr", []string{"host1", "host2"}, []string{}, "api-key", "some_uuid", "", "ams"}
+ s4 := ServiceType{"sCr", []string{"host1", "host2"}, []string{}, "api-key", "some_uuid", "", "", "ams"}
_, err4 := CreateServiceType(s4, mockstore, *cfg)
// test the case of unsupported auth method
- s5 := ServiceType{"sCr", []string{"host1", "host2"}, []string{"x509", "oidc"}, "unsup_method", "some_uuid", "", "ams"}
+ s5 := ServiceType{"sCr", []string{"host1", "host2"}, []string{"x509", "oidc"}, "unsup_method", "some_uuid", "", "", "ams"}
_, err5 := CreateServiceType(s5, mockstore, *cfg)
// test the case of empty name
- s6 := ServiceType{"", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "ams"}
+ s6 := ServiceType{"", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "", "ams"}
_, err6 := CreateServiceType(s6, mockstore, *cfg)
// test the case of empty auth method
- s8 := ServiceType{"sCr", []string{"host1", "host2"}, []string{"x509", "oidc"}, "", "uuid1", "", "ams"}
+ s8 := ServiceType{"sCr", []string{"host1", "host2"}, []string{"x509", "oidc"}, "", "uuid1", "", "", "ams"}
_, err8 := CreateServiceType(s8, mockstore, *cfg)
// test the case of empty hosts
- s9 := ServiceType{"sCr", []string{}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "ams"}
+ s9 := ServiceType{"sCr", []string{}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "", "ams"}
_, err9 := CreateServiceType(s9, mockstore, *cfg)
// test the case of empty type
- s10 := ServiceType{"sCr", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "", ""}
+ s10 := ServiceType{"sCr", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "", ""}
_, err10 := CreateServiceType(s10, mockstore, *cfg)
// test the case of unsupported type type
- s11 := ServiceType{"sCr", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "unsup_type"}
+ s11 := ServiceType{"sCr", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "", "unsup_type"}
_, err11 := CreateServiceType(s11, mockstore, *cfg)
suite.Equal(s1.Name, res1[0].Name)
@@ -107,7 +107,7 @@ func (suite *ServiceTestSuite) TestFindServiceTypeByName() {
mockstore.SetUp()
// normal case
- expS1 := ServiceType{"s1", []string{"host1", "host2", "host3"}, []string{"x509", "oidc"}, "api-key", "uuid1", "2018-05-05T18:04:05Z", "ams"}
+ expS1 := ServiceType{"s1", []string{"host1", "host2", "host3"}, []string{"x509", "oidc"}, "api-key", "uuid1", "2018-05-05T18:04:05Z", "", "ams"}
ser1, err1 := FindServiceTypeByName("s1", mockstore)
// not found case
@@ -133,7 +133,7 @@ func (suite *ServiceTestSuite) TestFindServiceTypeByUUID() {
mockstore.SetUp()
// normal case
- expS1 := ServiceType{"s1", []string{"host1", "host2", "host3"}, []string{"x509", "oidc"}, "api-key", "uuid1", "2018-05-05T18:04:05Z", "ams"}
+ expS1 := ServiceType{"s1", []string{"host1", "host2", "host3"}, []string{"x509", "oidc"}, "api-key", "uuid1", "2018-05-05T18:04:05Z", "", "ams"}
ser1, err1 := FindServiceTypeByUUID("uuid1", mockstore)
// not found case
@@ -218,8 +218,8 @@ func (suite *ServiceTestSuite) TestUpdateService() {
_ = cfg.ConfigSetUp("../config/configuration-test-files/test-conf.json")
// original service type
- qOriginal := stores.QServiceType{"sCr", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "ams"}
- original := ServiceType{"sCr", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "ams"}
+ qOriginal := stores.QServiceType{"sCr", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "", "ams"}
+ original := ServiceType{"sCr", []string{"host1", "host2"}, []string{"x509", "oidc"}, "api-key", "uuid1", "", "", "ams"}
mockstore.ServiceTypes = append(mockstore.ServiceTypes, qOriginal)
// test the normal case
diff --git a/setup.py b/setup.py
index 9cc1ebc..c9d7ef6 100644
--- a/setup.py
+++ b/setup.py
@@ -13,5 +13,5 @@
'./bin/argo-api-authn-scripts/ams-create-users-cloud-info.py'],
package_dir={'argo_api_authn_scripts': './bin/argo-api-authn-scripts/'},
packages=['argo_api_authn_scripts'],
- install_requires=['defusedxml==0.5.0', 'requests==2.20', 'python-ldap==3.4.0']
+ install_requires=['defusedxml==0.7.1', 'python-ldap==3.4.0', 'argo-ams-library==0.5.9', 'requests']
)
diff --git a/stores/models.go b/stores/models.go
index 72d786b..af77f03 100644
--- a/stores/models.go
+++ b/stores/models.go
@@ -12,6 +12,7 @@ type QServiceType struct {
AuthMethod string `json:"auth_method" bson:"auth_method"`
UUID string `json:"uuid" bson:"uuid"`
CreatedOn string `json:"created_on,omitempty" bson:"created_on,omitempty"`
+ UpdatedOn string `json:"updated_on,omitempty" bson:"updated_on,omitempty"`
Type string `json:"type" bson:"type"`
}
@@ -24,6 +25,7 @@ type QBinding struct {
AuthType string `json:"auth_type" bson:"auth_type"`
UniqueKey string `json:"unique_key,omitempty"`
CreatedOn string `json:"created_on,omitempty" bson:"created_on,omitempty"`
+ UpdatedOn string `json:"updated_on,omitempty" bson:"updated_on,omitempty"`
LastAuth string `json:"last_auth,omitempty" bson:"last_auth,omitempty"`
}
@@ -36,6 +38,7 @@ type QBasicAuthMethod struct {
Type string `json:"type" bson:"type"`
UUID string `json:"uuid" bson:"uuid"`
CreatedOn string `json:"created_on" bson:"created_on"`
+ UpdatedOn string `json:"updated_on,omitempty" bson:"updated_on,omitempty"`
}
type QApiKeyAuthMethod struct {
diff --git a/stores/mongo.go b/stores/mongo.go
index 9ac0ff7..0bf1ee1 100644
--- a/stores/mongo.go
+++ b/stores/mongo.go
@@ -400,7 +400,6 @@ func (mongo *MongoStore) UpdateAuthMethod(original QAuthMethod, updated QAuthMet
db := mongo.Session.DB(mongo.Database)
c := db.C("auth_methods")
-
if err := c.Update(original, updated); err != nil {
log.WithFields(
log.Fields{