diff --git a/schema/vc/mkSchema.py b/schema/vc/mkSchema.py new file mode 100755 index 0000000..a524ec2 --- /dev/null +++ b/schema/vc/mkSchema.py @@ -0,0 +1,145 @@ +#! /bin/python3 + +import sys +import json +from pathlib import Path + + +def loadJSON(json_file): + with open(json_file) as json_file: + return json.load(json_file) + +def p(message, writetolog=False): + if writetolog: + write_log(message) + else: + print(message) + +def pj(the_json, writetolog=False): + p(json.dumps(the_json, indent=4, sort_keys=False), writetolog) + + +def write_file(contents, filepath, mkpath=True, overwrite=False, type='txt'): + if mkpath: + Path(filepath).mkdir(parents=True, exist_ok=overwrite) + + if overwrite: + f = open(filepath, "w") + else: + f = open(filepath, "a") + + match type: + case 'yaml': + yaml.preserve_quotes = True + yaml.dump(contents, f) + case 'json': + f.write(json.dumps(contents,sort_keys=False, indent=4, ensure_ascii=False,separators=(',', ':'))) + case _: + # assume text + f.write(contents+"\n") + + f.close() + +def replace_capitals(s): + return ''.join(['' + ("_" + char.lower()) if char.isupper() else char for char in s]).strip() + +def covert_schemaname(attributeName): + # Attributes need to be rename to claims + # as a general rule of thumb: + # + # eduPerson, voPerson and Schac schema names are just lowercased ad get added an underscore + # + # for the attrbute name: if a captical is found, it is replaced with a lower and prefixed with an underscore. + # + # sp eduPersonScopedAffiliation becomes: eduperson_scoped_affiliation + # + s= attributeName + + if s.startswith('eduPerson'): + return ("eduperson" + fixName(replace_capitals(s[9:]))) + elif s.startswith('voPerson'): + return ("voperson" + fixName(replace_capitals(s[7:]))) + elif s.startswith('Schac'): + return ("schac" + fixName(replace_capitals(s[5:]))) + else: + return (fixName(replace_capitals(s))) + +def fixName(name): + return name.replace("_i_d", "_id").replace("_d_n", "_dn").replace("_u_r_i", "_uri").replace("_s_m_i_m_e", "_smime") + +def mapType(equality, multivalued = False): + + if multivalued: + match equality: + case "caseExactMatch" | "caseIgnoreMatch": + return "string" + case "integerMatch": + return "integer" + case "numericStringMatch": + return "number" + else: + return None + +def main(argv): + schemaFile = { + "vcdm2.0": "schac_1_6_0.json_vcdm.json", + "sdjwt": "schac_1_6_0.json_sdjwt.json" + } + + # Generate object properties based on ldif schema,coverted to json by chatGTP + # The resulting schac_ldif.json was added for reference + # + schemaJSON = loadJSON('schac_ldap.json') + object_props = {} + att = schemaJSON['schema']['attributes'] + + for a in att: + name = covert_schemaname(a['name']) + object_props[name] = { + "type": mapType(a['equality'], ('singleValue' in a)), + "description": a['description'], + } + + # TODO: validate these + # TODO: we still have several format and pattern definitions missing + match a['name']: + case "schacHomeOrganizationType" | "schacUserPresenceID" |"schacPersonalPosition" | "schacPersonalUniqueCode" : + object_props[name]['type'] = "array" + object_props[name]['anyof'] = { "type": "uri" } + + case "schacGender": + object_props[name]['type'] = "integer" + object_props[name]['deprecated'] = True + + case "schacDateOfBirth": + object_props[name]['maxLength'] = 8 + + case "schacCountryOfCitizenship" | "schacCountryOfResidence": + object_props[name]['maxLength'] = 2 + + for type,filename in schemaFile.items(): + schema = { + "$id": "https://refeds.org/schemas/vc/" + filename, + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$comment": "This schema implements SCHAC (SCHema for ACademia) version 1.6.0 (23 May 2022) - https://refeds.org/specifications/schac - This schema is maintained by REFEDs (https://refeds.org). The mission of REFEDS (the Research and Education FEDerations group) is to be the voice that articulates the mutual needs of research and education identity federations worldwide.", + "title": "SCHACcredentials", + "description": "Schema for verifiable credential claims describing a user in the context of SCHAC", + "type": "object", + "properties": { + "credentialSubject": { + "type": "object", + "properties": {} + } + } + } + + match type: + case "vcdm2.0": + schema["properties"]["credentialSubject"]["properties"] = object_props + case "sdjwt": + schema["properties"] = object_props + + write_file(schema, filename, mkpath=False, overwrite=True, type='json') + +if __name__ == "__main__": + main(sys.argv[1:]) \ No newline at end of file diff --git a/schema/vc/schac_1_6_0.json_sdjwt.json b/schema/vc/schac_1_6_0.json_sdjwt.json new file mode 100644 index 0000000..6ecb65e --- /dev/null +++ b/schema/vc/schac_1_6_0.json_sdjwt.json @@ -0,0 +1,82 @@ +{ + "$id":"https://refeds.org/schemas/vc/schac_1_6_0.json_sdjwt.json", + "$schema":"https://json-schema.org/draft/2020-12/schema", + "$comment":"This schema implements SCHAC (SCHema for ACademia) version 1.6.0 (23 May 2022) - https://refeds.org/specifications/schac - This schema is maintained by REFEDs (https://refeds.org). The mission of REFEDS (the Research and Education FEDerations group) is to be the voice that articulates the mutual needs of research and education identity federations worldwide.", + "title":"SCHACcredentials", + "description":"Schema for verifiable credential claims describing a user in the context of SCHAC", + "type":"object", + "properties":{ + "schac_mother_tongue":{ + "type":"string", + "description":"RFC 3066 code for preferred language of communication" + }, + "schac_gender":{ + "type":"integer", + "description":"Representation of human sex (see ISO 5218). Deprecated as of SCHAC 1.6.0", + "deprecated":true + }, + "schac_date_of_birth":{ + "type":"number", + "description":"Date of birth (format YYYYMMDD, only numeric chars)", + "maxLength":8 + }, + "schac_place_of_birth":{ + "type":"string", + "description":"Birth place of a person" + }, + "schac_country_of_citizenship":{ + "type":"string", + "description":"Country of citizenship of a person. Format two-letter acronym according to ISO 3166-1 alpha 2", + "maxLength":2 + }, + "schac_sn1":{ + "type":"string", + "description":"First surname of a person" + }, + "schac_sn2":{ + "type":"string", + "description":"Second surname of a person" + }, + "schac_personal_title":{ + "type":"string", + "description":"RFC1274: personal title" + }, + "schac_home_organization":{ + "type":"string", + "description":"Domain name of the home organization" + }, + "schac_home_organization_type":{ + "type":"array", + "description":"Type of the home organization", + "anyof":{ + "type":"uri" + } + }, + "schac_country_of_residence":{ + "type":"string", + "description":"Country of residence of a person. Format two-letter acronym according to ISO 3166-1 alpha 2", + "maxLength":2 + }, + "schac_user_presence_id":{ + "type":"array", + "description":"Used to store a set of values related to the network presence", + "anyof":{ + "type":"uri" + } + }, + "schac_personal_position":{ + "type":"array", + "description":"Position inside an institution", + "anyof":{ + "type":"uri" + } + }, + "schac_personal_unique_code":{ + "type":"array", + "description":"unique code for the subject", + "anyof":{ + "type":"uri" + } + } + } +} \ No newline at end of file diff --git a/schema/vc/schac_1_6_0.json_vcdm.json b/schema/vc/schac_1_6_0.json_vcdm.json new file mode 100644 index 0000000..0973dba --- /dev/null +++ b/schema/vc/schac_1_6_0.json_vcdm.json @@ -0,0 +1,87 @@ +{ + "$id":"https://refeds.org/schemas/vc/schac_1_6_0.json_vcdm.json", + "$schema":"https://json-schema.org/draft/2020-12/schema", + "$comment":"This schema implements SCHAC (SCHema for ACademia) version 1.6.0 (23 May 2022) - https://refeds.org/specifications/schac - This schema is maintained by REFEDs (https://refeds.org). The mission of REFEDS (the Research and Education FEDerations group) is to be the voice that articulates the mutual needs of research and education identity federations worldwide.", + "title":"SCHACcredentials", + "description":"Schema for verifiable credential claims describing a user in the context of SCHAC", + "type":"object", + "properties":{ + "credentialSubject":{ + "type":"object", + "properties":{ + "schac_mother_tongue":{ + "type":"string", + "description":"RFC 3066 code for preferred language of communication" + }, + "schac_gender":{ + "type":"integer", + "description":"Representation of human sex (see ISO 5218). Deprecated as of SCHAC 1.6.0", + "deprecated":true + }, + "schac_date_of_birth":{ + "type":"number", + "description":"Date of birth (format YYYYMMDD, only numeric chars)", + "maxLength":8 + }, + "schac_place_of_birth":{ + "type":"string", + "description":"Birth place of a person" + }, + "schac_country_of_citizenship":{ + "type":"string", + "description":"Country of citizenship of a person. Format two-letter acronym according to ISO 3166-1 alpha 2", + "maxLength":2 + }, + "schac_sn1":{ + "type":"string", + "description":"First surname of a person" + }, + "schac_sn2":{ + "type":"string", + "description":"Second surname of a person" + }, + "schac_personal_title":{ + "type":"string", + "description":"RFC1274: personal title" + }, + "schac_home_organization":{ + "type":"string", + "description":"Domain name of the home organization" + }, + "schac_home_organization_type":{ + "type":"array", + "description":"Type of the home organization", + "anyof":{ + "type":"uri" + } + }, + "schac_country_of_residence":{ + "type":"string", + "description":"Country of residence of a person. Format two-letter acronym according to ISO 3166-1 alpha 2", + "maxLength":2 + }, + "schac_user_presence_id":{ + "type":"array", + "description":"Used to store a set of values related to the network presence", + "anyof":{ + "type":"uri" + } + }, + "schac_personal_position":{ + "type":"array", + "description":"Position inside an institution", + "anyof":{ + "type":"uri" + } + }, + "schac_personal_unique_code":{ + "type":"array", + "description":"unique code for the subject", + "anyof":{ + "type":"uri" + } + } + } + } + } +} \ No newline at end of file diff --git a/schema/vc/schac_ldap.json b/schema/vc/schac_ldap.json new file mode 100644 index 0000000..92aa10b --- /dev/null +++ b/schema/vc/schac_ldap.json @@ -0,0 +1,186 @@ +{ + "schema": { + "version": "1.6.0", + "description": "SCHema for ACademia (SCHAC) Attribute definitions for individual data", + "objectIdentifiers": { + "GEANT": "1.3.6.1.4.1.25178", + "schac": "GEANT:1", + "schacExperimental": "schac:0", + "schacObjectClass": "schac:1", + "schacAttributeType": "schac:2", + "schacExpObjClass": "schacExperimental:1", + "schacExpAttr": "schacExperimental:2" + }, + "attributes": [ + { + "id": "schacAttributeType:1", + "name": "schacMotherTongue", + "description": "RFC 3066 code for preferred language of communication", + "equality": "caseExactMatch", + "singleValue": true, + "syntaxOID": "1.3.6.1.4.1.1466.115.121.1.15", + "examples": ["fr", "es-ES"] + }, + { + "id": "schacAttributeType:2", + "name": "schacGender", + "description": "Representation of human sex (see ISO 5218). Deprecated as of SCHAC 1.6.0", + "equality": "integerMatch", + "singleValue": true, + "syntaxOID": "1.3.6.1.4.1.1466.115.121.1.27", + "format": { + "0": "Not known", + "1": "Male", + "2": "Female", + "9": "Not specified" + }, + "example": "2" + }, + { + "id": "schacAttributeType:3", + "name": "schacDateOfBirth", + "description": "Date of birth (format YYYYMMDD, only numeric chars)", + "equality": "numericStringMatch", + "ordering": "numericStringOrderingMatch", + "substring": "numericStringSubstringsMatch", + "singleValue": true, + "syntaxOID": "1.3.6.1.4.1.1466.115.121.1.36", + "example": "19660412" + }, + { + "id": "schacAttributeType:4", + "name": "schacPlaceOfBirth", + "description": "Birth place of a person", + "equality": "caseIgnoreMatch", + "ordering": "caseIgnoreOrderingMatch", + "substring": "caseIgnoreSubstringsMatch", + "singleValue": true, + "syntaxOID": "1.3.6.1.4.1.1466.115.121.1.15", + "example": "Algeciras, Spain" + }, + { + "id": "schacAttributeType:5", + "name": "schacCountryOfCitizenship", + "description": "Country of citizenship of a person. Format two-letter acronym according to ISO 3166-1 alpha 2", + "equality": "caseIgnoreMatch", + "singleValue": true, + "syntaxOID": "1.3.6.1.4.1.1466.115.121.1.15", + "example": "es" + }, + { + "id": "schacAttributeType:6", + "name": "schacSn1", + "description": "First surname of a person", + "equality": "caseIgnoreMatch", + "ordering": "caseIgnoreOrderingMatch", + "substring": "caseIgnoreSubstringsMatch", + "singleValue": true, + "syntaxOID": "1.3.6.1.4.1.1466.115.121.1.15", + "examples": [ + "Lopez de la Moraleda", + "Wolniewicz" + ] + }, + { + "id": "schacAttributeType:7", + "name": "schacSn2", + "description": "Second surname of a person", + "equality": "caseIgnoreMatch", + "ordering": "caseIgnoreOrderingMatch", + "substring": "caseIgnoreSubstringsMatch", + "singleValue": true, + "syntaxOID": "1.3.6.1.4.1.1466.115.121.1.15", + "examples": [ + "de Las Altas Alcurnias", + "Gorecka" + ] + }, + { + "id": "schacAttributeType:8", + "name": "schacPersonalTitle", + "description": "RFC1274: personal title", + "equality": "caseIgnoreMatch", + "substring": "caseIgnoreSubstringsMatch", + "singleValue": true, + "syntaxOID": "1.3.6.1.4.1.1466.115.121.1.15", + "example": "Prof" + }, + { + "id": "schacAttributeType:9", + "name": "schacHomeOrganization", + "description": "Domain name of the home organization", + "equality": "caseIgnoreMatch", + "substring": "caseIgnoreSubstringsMatch", + "singleValue": true, + "syntaxOID": "1.3.6.1.4.1.1466.115.121.1.15", + "example": "tut.fi" + }, + { + "id": "schacAttributeType:10", + "name": "schacHomeOrganizationType", + "description": "Type of the home organization", + "equality": "caseIgnoreMatch", + "syntaxOID": "1.3.6.1.4.1.1466.115.121.1.15", + "examples": [ + "urn:schac.org:schac:homeOrganizationType:int:university", + "urn:schac.org:schac:homeOrganizationType:int:uas", + "urn:schac.org:schac:homeOrganizationType:int:research-institution", + "urn:schac.org:schac:homeOrganizationType:int:university-hospital", + "urn:schac.org:schac:homeOrganizationType:int:nren", + "urn:schac.org:schac:homeOrganizationType:int:other", + "urn:schac.org:schac:homeOrganizationType:ch:vho", + "urn:schac.org:schac:homeOrganizationType:es:opi" + ] + }, + { + "id": "schacAttributeType:11", + "name": "schacCountryOfResidence", + "description": "Country of residence of a person. Format two-letter acronym according to ISO 3166-1 alpha 2", + "equality": "caseIgnoreMatch", + "singleValue": true, + "syntaxOID": "1.3.6.1.4.1.1466.115.121.1.15", + "example": "es" + }, + { + "id": "schacAttributeType:12", + "name": "schacUserPresenceID", + "description": "Used to store a set of values related to the network presence", + "equality": "caseExactMatch", + "substring": "caseExactSubstringsMatch", + "syntaxOID": "1.3.6.1.4.1.1466.115.121.1.15", + "examples": [ + "xmpp:pepe@im.univx.es", + "sip:jose.perez@myweb.es", + "sip:+34-95-505-6600@univx.es;transport=TCP;user=phone", + "sips:alice@atlanta.com?subject=project%20x&priority=urgent", + "h323:pepe@myweb.fi:808;pars", + "skype:pepe.perez" + ] + }, + { + "id": "schacAttributeType:13", + "name": "schacPersonalPosition", + "description": "Position inside an institution", + "equality": "caseIgnoreMatch", + "substring": "caseIgnoreSubstringsMatch", + "syntaxOID": "1.3.6.1.4.1.1466.115.121.1.15", + "example": "urn:schac.org:schac:personalPosition:pl:umk.pl:programmer" + }, + { + "id": "schacAttributeType:14", + "name": "schacPersonalUniqueCode", + "description": "unique code for the subject", + "equality": "caseIgnoreMatch", + "ordering": "caseIgnoreOrderingMatch", + "substring": "caseIgnoreSubstringsMatch", + "syntaxOID": "1.3.6.1.4.1.1466.115.121.1.15", + "examples": [ + "urn:schac.org:schac:personalUniqueCode:int:studentID::", + "urn:schac.org:schac:personalUniqueCode:fi:tut.fi:hetu:010161-995A", + "urn:schac.org:schac:personalUniqueCode:es:uma:estudiante:a3b123c12", + "urn:schac.org:schac:personalUniqueCode:se:LIN:studentId:20001234" + ] + } + ] + } +} \ No newline at end of file diff --git a/schema/vc/schac_ldif.json b/schema/vc/schac_ldif.json new file mode 100644 index 0000000..716a92f --- /dev/null +++ b/schema/vc/schac_ldif.json @@ -0,0 +1,288 @@ +{ + "dn": "cn=schac,cn=schema,cn=config", + "objectClass": "olcSchemaConfig", + "cn": "schac", + "olcObjectIdentifier": [ + "GEANT 1.3.6.1.4.1.25178", + "schac GEANT:1", + "schacExperimental schac:0", + "schacObjectClass schac:1", + "schacAttributeType schac:2", + "schacExpObjClass schacExperimental:1", + "schacExpAttr schacExperimental:2" + ], + "olcAttributeTypes": [ + { + "id": "schacAttributeType:1", + "NAME": "schacMotherTongue", + "DESC": "RFC 3066 code for preferred language of communication", + "EQUALITY": "caseExactMatch", + "SINGLE-VALUE": true, + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:2", + "NAME": "schacGender", + "DESC": "Deprecated as of SCHAC 1.6.0", + "EQUALITY": "integerMatch", + "SINGLE-VALUE": true, + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.27" + }, + { + "id": "schacAttributeType:3", + "NAME": "schacDateOfBirth", + "DESC": "Date of birth (format YYYYMMDD, only numeric chars)", + "EQUALITY": "numericStringMatch", + "ORDERING": "numericStringOrderingMatch", + "SUBSTR": "numericStringSubstringsMatch", + "SINGLE-VALUE": true, + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.36" + }, + { + "id": "schacAttributeType:4", + "NAME": "schacPlaceOfBirth", + "DESC": "Birth place of a person", + "EQUALITY": "caseIgnoreMatch", + "ORDERING": "caseIgnoreOrderingMatch", + "SUBSTR": "caseIgnoreSubstringsMatch", + "SINGLE-VALUE": true, + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:5", + "NAME": "schacCountryOfCitizenship", + "DESC": "Country of citizenship of a person. Format two-letter acronym according to ISO 3166-1 alpha 2", + "EQUALITY": "caseIgnoreMatch", + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:6", + "NAME": "schacSn1", + "DESC": "First surname of a person", + "EQUALITY": "caseIgnoreMatch", + "ORDERING": "caseIgnoreOrderingMatch", + "SUBSTR": "caseIgnoreSubstringsMatch", + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:7", + "NAME": "schacSn2", + "DESC": "Second surname of a person", + "EQUALITY": "caseIgnoreMatch", + "ORDERING": "caseIgnoreOrderingMatch", + "SUBSTR": "caseIgnoreSubstringsMatch", + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:8", + "NAME": "schacPersonalTitle", + "DESC": "RFC1274: personal title", + "EQUALITY": "caseIgnoreMatch", + "SUBSTR": "caseIgnoreSubstringsMatch", + "SINGLE-VALUE": true, + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:9", + "NAME": "schacHomeOrganization", + "DESC": "Domain name of the home organization", + "EQUALITY": "caseIgnoreMatch", + "SUBSTR": "caseIgnoreSubstringsMatch", + "SINGLE-VALUE": true, + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:10", + "NAME": "schacHomeOrganizationType", + "DESC": "Type of the home organization", + "EQUALITY": "caseIgnoreMatch", + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:11", + "NAME": "schacCountryOfResidence", + "DESC": "Country of residence of a person. Format two-letter acronym according to ISO 3166-1 alpha 2", + "EQUALITY": "caseIgnoreMatch", + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:12", + "NAME": "schacUserPresenceID", + "DESC": "Used to store a set of values related to the network presence", + "EQUALITY": "caseExactMatch", + "SUBSTR": "caseExactSubstringsMatch", + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:13", + "NAME": "schacPersonalPosition", + "DESC": "Position inside an institution", + "EQUALITY": "caseIgnoreMatch", + "SUBSTR": "caseIgnoreSubstringsMatch", + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:14", + "NAME": "schacPersonalUniqueCode", + "DESC": "unique code for the subject", + "EQUALITY": "caseIgnoreMatch", + "ORDERING": "caseIgnoreOrderingMatch", + "SUBSTR": "caseIgnoreSubstringsMatch", + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:15", + "NAME": "schacPersonalUniqueID", + "DESC": "Unique identifier for the subject", + "EQUALITY": "caseExactMatch", + "ORDERING": "caseExactOrderingMatch", + "SUBSTR": "caseExactSubstringsMatch", + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:17", + "NAME": "schacExpiryDate", + "DESC": "Date from which the set of data is to be considered invalid (format YYYYMMDDhhmmssZ)", + "EQUALITY": "generalizedTimeMatch", + "ORDERING": "generalizedTimeOrderingMatch", + "SINGLE-VALUE": true, + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.24" + }, + { + "id": "schacAttributeType:18", + "NAME": "schacUserPrivateAttribute", + "DESC": "Set of denied access attributes", + "EQUALITY": "caseIgnoreIA5Match", + "SUBSTR": "caseIgnoreIA5SubstringsMatch", + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.26" + }, + { + "id": "schacAttributeType:19", + "NAME": "schacUserStatus", + "DESC": "Used to store a set of status of a person as user of services", + "EQUALITY": "caseIgnoreMatch", + "SUBSTR": "caseIgnoreSubstringsMatch", + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:20", + "NAME": "schacProjectMembership", + "DESC": "Name of the project", + "EQUALITY": "caseIgnoreMatch", + "SUBSTR": "caseIgnoreSubstringsMatch", + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacAttributeType:21", + "NAME": "schacProjectSpecificRole", + "DESC": "Used to store a set of roles of a person inside a project", + "EQUALITY": "caseIgnoreMatch", + "SUBSTR": "caseIgnoreSubstringsMatch", + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.15" + }, + { + "id": "schacExpAttr:3", + "NAME": "schacYearOfBirth", + "DESC": "Year of birth (format YYYY, only numeric chars)", + "EQUALITY": "numericStringMatch", + "ORDERING": "numericStringOrderingMatch", + "SUBSTR": "numericStringSubstringsMatch", + "SINGLE-VALUE": true, + "SYNTAX": "1.3.6.1.4.1.1466.115.121.1.36" + } + ], + "olcObjectClasses": [ + { + "id": "schacObjectClass:1", + "NAME": "schacPersonalCharacteristics", + "DESC": "Personal characteristics describe the individual person represented by the entry", + "AUXILIARY": true, + "MAY": [ + "schacMotherTongue", + "schacDateOfBirth", + "schacPlaceOfBirth", + "schacCountryOfCitizenship", + "schacSn1", + "schacSn2", + "schacPersonalTitle" + ] + }, + { + "id": "schacObjectClass:2", + "NAME": "schacContactLocation", + "DESC": "Primary means of locating and contacting potential collaborators and other persons-of-interest at peer institutions", + "AUXILIARY": true, + "MAY": [ + "schacHomeOrganization", + "schacHomeOrganizationType", + "schacCountryOfResidence", + "schacUserPresenceID" + ] + }, + { + "id": "schacObjectClass:3", + "NAME": "schacEmployeeInfo", + "DESC": "Employee information includes attributes that have relevance to the employee role, such as position, office hours, and job title", + "AUXILIARY": true, + "MAY": [ + "schacPersonalPosition" + ] + }, + { + "id": "schacObjectClass:4", + "NAME": "schacLinkageIdentifiers", + "DESC": "Used to link a directory entry with records in external data stores or other directory entries", + "AUXILIARY": true, + "MAY": [ + "schacPersonalUniqueCode", + "schacPersonalUniqueID" + ] + }, + { + "id": "schacObjectClass:5", + "NAME": "schacEntryMetadata", + "DESC": "Used to contain information about the entry itself, often its status, birth, and death", + "AUXILIARY": true, + "MAY": [ + "schacExpiryDate" + ] + }, + { + "id": "schacObjectClass:6", + "NAME": "schacEntryConfidentiality", + "DESC": "Used to indicate whether an entry is visible publicly, visible only to affiliates of the institution, or not visible at all", + "AUXILIARY": true, + "MAY": [ + "schacUserPrivateAttribute" + ] + }, + { + "id": "schacObjectClass:7", + "NAME": "schacUserEntitlements", + "DESC": "Authorization for services", + "AUXILIARY": true, + "MAY": [ + "schacUserStatus" + ] + }, + { + "id": "schacObjectClass:8", + "NAME": "schacGroupMembership", + "DESC": "Groups used to provide/restrict authorization to entries and attributes", + "AUXILIARY": true, + "MAY": [ + "schacProjectMembership", + "schacProjectSpecificRole" + ] + }, + { + "id": "schacExpObjClass:1", + "NAME": "schacExperimentalOC", + "DESC": "Experimental Object Class", + "AUXILIARY": true, + "MAY": [ + "schacYearOfBirth" + ] + } + ] +} \ No newline at end of file