liveapicreator-admin-cli
Version:
The NodeJS command line utility for 'CA Live API Creator' DevOps Administration from CA Technologies
72 lines • 21.7 kB
JSON
[
{
"name": "HTTPAuth",
"comments": null,
"auth_type_ident": 3,
"class_name": "com.kahuna.server.auth.HttpAuthProvider",
"javascript_authprovider_code": null,
"bootstrap_config_value": null,
"param_map": null,
"get_config_info_code": "var pkField = configInfo.addConfigField();\npkField.name = \"AuthPublicKeyText\";\npkField.description = \"The public key to verify incoming authentication\";\npkField.display = \"Auth public key\";\npkField.length = 500;\n\nvar pkAlgoField = configInfo.addConfigField();\npkAlgoField.name = \"AuthPublicKeyAlgorithm\";\npkAlgoField.description = \"The algorithm for the public key\";\npkAlgoField.display = \"Auth public key algorithm\";\npkAlgoField.length = 20;\n\nvar jwtHeaderName = configInfo.addConfigField();\njwtHeaderName.name = \"AuthHeaderName\";\njwtHeaderName.description = \"Name of HTTP header containing authentication, used for caching (see docs for details)\";\njwtHeaderName.display = \"Auth Header Name\";\njwtHeaderName.length = 20;\n",
"configure_code": null,
"get_login_info_code": "var auth = servletRequest.getHeader(\"Authorization\");\nif (auth && auth.startsWith(\"Bearer \")) {\n // In this very simple example, we just assume that the header is OK\n\t\t// Obviously, in the real world, you would want to verify that!\n loginInfo.loginStatus = \"OK\";\n\n\t\t// The authentication information should provide you with enough\n\t\t// information to determine the caller's account. Here we just\n\t\t// hard-code it.\n loginInfo.accountIdent = 1000;\n return;\n}\n// If the request did not contain enough information, let's send back\n// a URL to tell the caller where to go for authentication\nif ( ! authProvider.variables[\"randomState\"]) {\n print(\"Get login info: generate random state\");\n var RG = Java.type(\"com.kahuna.logic.lib.crypto.RandomGenerator\");\n authProvider.variables.randomState = RG.generateRandomString(50);\n}\nvar clientId = \"12345678901234567890\";\nvar redirectUri = \"http://localhost:8080/APICreator\";\nloginInfo.redirectUrl =\n \"https://dev-1234567.oktapreview.com/oauth2/default/v1/authorize?client_id=\" +\n clientId + \"&response_type=token&scope=openid&redirect_uri=\" + redirectUri +\n \"&state=\" + authProvider.variables.randomState +\n \"&nonce=\" + authProvider.variables.randomState;\n\t\n",
"auth_code": null,
"account_ident": null
},
{
"name": "JSAUth",
"comments": "test",
"auth_type_ident": 2,
"class_name": "com.kahuna.server.auth.JavaScriptAuthProvider",
"javascript_authprovider_code": "out = java.lang.System.out;\n\nfunction create() {\n\n var result = {};\n var configSetup = {\n logonApiKey : '',\n loginBaseURL : '',\n loginGroupURL : '',\n keyLifetimeMinutes : 60\n };\n\n\n // This function is called by API Creator when the user enters a value\n // for the parameters specified by getConfigInfo and clicks Save.\n // Returns configuration values which API Creator will save into Admin DB;\n // these are exported in the json config file\n result.configure = function configure(myConfig) {\n configSetup.logonApiKey = myConfig.logonApiKey || 'demo_full'; // supply, or default\n configSetup.loginBaseURL = myConfig.loginBaseURL || 'http://localhost:8080/rest/default/v1/...';\n configSetup.keyLifetimeMinutes = myConfig.keyLifetimeMinutes || 60;\n };\n\n\n // Main crux of Auth Provider - called by API Server on post to @authenticate, to return list of Roles\n // NOTE: the function configure must be called first - this will validate the user/pw\n\n // The argument passed in will contain whatever values were provided to the @authentication service.\n // If the caller is well-behaved, this should correspond to the parameters described by getLoginInfo,\n // but you should not depend on that.\n\n // This function must return an object containing just an error message if the authentication failed.\n // If the authentication succeeded, then it must return an object with the following properties:\n result.authenticate = function authenticate(payload) {\n\n out.println(\"Authentication called...\");\n\n var roles = [];\n var errorMsg = null;\n var myUserData = [];\n var params = null;\n\n try {\n if (payload.username == 'admin' || payload.username == 'demo') {\n out.println(\"Authentication - default admin/demo/ user - good to go..\");\n roles.push('Full access'); // HARD CODED FOR DEMO -Some examples use this as their role name\n roles.push('API Owner'); // HARD CODED FOR DEMO (we even ignore the pwd) for full access\n errorMsg = null; // authorized successfully\n myUserData.push(\"Free Form Data\");\n }\n }\n catch (e) {\n errorMsg = e.message;\n }\n\n var autResponse = {\n errorMessage : errorMsg,\n roleNames : roles,\n userIdentifier : payload.username,\n keyExpiration : new Date(+new Date()\n + (+configSetup.keyLifetimeMinutes) * 60 * 1000),\n userData : myUserData,\n lastLogin : {\n datetime : null,\n ipAddress : null\n }\n };\n return autResponse;\n };\n\n // FUNCTION getLoginInfo is used to create the login dialog - DO NOT CHANGE\n // This function is called by API Server when a client needs to know what kind of information is required for authentication.\n // Basically, this describes what the login dialog should look like (assuming the client is an interactive application).\n result.getLoginInfo = function getLoginInfo() {\n return {\n fields : [\n {\n name : \"username\",\n display : \"Username\",\n description : \"Enter your First Name\",\n type : \"text\",\n length : 40,\n helpURL : \"http://liveapicreator.ca.com\"\n },\n {\n name : \"password\",\n display : \"Password\",\n description : \"Enter your Last Name as Password\",\n type : \"password\",\n length : 40,\n helpURL : \"http://liveapicreator.ca.com/\"\n } ],\n links : [\n\n ]\n };\n };\n\n //getConfigInfo is used to generate the Auth Provider User Interface to prompt for variables passed to the system at authentication time\n result.getConfigInfo = function getConfigInfo() {\n return {\n current : {\n \"keyLifetimeMinutes\" : configSetup.keyLifetimeMinutes,\n \"logonApiKey\" : configSetup.logonApiKey,\n \"loginBaseURL\" : configSetup.loginBaseURL\n },\n fields : [ {\n name : \"logonApiKey\",\n display : \"logonApiKey\",\n type : \"text\",\n length : 60,\n helpURL : \"\"\n }, {\n name : \"loginBaseURL\",\n display : \"loginBaseURL\",\n type : \"text\",\n length : 120,\n helpURL : \"\"\n }, {\n name : \"loginGroupURL\",\n display : \"loginGroupURL\",\n type : \"text\",\n length : 120,\n helpURL : \"\"\n }, {\n name : \"keyLifetimeMinutes\",\n display : \"API Key Lifetime (Minutes)\",\n type : \"number\",\n length : 8,\n helpURL : \"http://www.liveapicreator.ca.com\"\n } ],\n links : []\n };\n };\n\n // returns object containing the 4 functions that define a Custom Authentication Provider:\n // getConfigInfo: function() {...}, configure: function(values) {...}, getLoginInfo: function() {...}, authenticate:\n\n return result;\n}\n",
"bootstrap_config_value": "create",
"param_map": "\"keyLifetimeMinutes\"=\"60\", \"loginBaseURL\"=\"http://localhost:8080/rest/default/b2bderbynw/v1/nw:Employees\", \"loginGroupURL\"=\"http://localhost:8080/rest/default/demo/v1/demo:employee\", \"logonApiKey\"=\"Bzn8jVyfOTiIpW6UQCgy\"",
"get_config_info_code": null,
"configure_code": null,
"get_login_info_code": null,
"auth_code": null,
"account_ident": null
},
{
"name": "SimpleLDAP",
"comments": null,
"auth_type_ident": 2,
"class_name": "com.kahuna.server.auth.JavaScriptAuthProvider",
"javascript_authprovider_code": "// This is a simple LDAP authentication provider for CA Live API Creator.\n// It connects to a public LDAP server (ldap.forumsys.com), which recognizes\n// a few users: boyle, curie, einstein, euclid, euler, gauss, newton, pasteur, tesla.\n// All users have the same password: \"password\" (without quotes).\n// Each user belongs to a group: chemists, mathematicians, or scientists.\n// Each user has an attribute named mail, and some users have an attribute named telephoneNumber.\n//\n// To adapt this to your specific LDAP environment, you will have to change the code to fit\n// your schema, e.g. what attribures are relevant, how you figure out which roles a user has, etc...\n//\n// You don't have to change the parameters, they are only shown as an example.\n// select this new auth provider for your project (API Properties -> Authentication Provider)\n// You should now be able to log in (e.g. using Data Explorer) as e.g. einstein/password.\n\nfunction SimpleLDAPAuthProvider () {\n var result = {};\n var configSetup = {};\n\n // This gets called first to pass in the required LDAP configuration values\n result.configure = function configure(myConfig) {\n configSetup.serverName = myConfig.serverName || \"ldap://ldap.forumsys.com\";\n configSetup.keyLifetimeMinutes = myConfig.keyLifetimeMinutes || 60;\n };\n\n // This gets called to validate the user payload against LDAP service\n result.authenticate = function authenticate(payload) {\n java.lang.System.out.println(\"Authenticating with LDAP: \" + payload.username);\n var authResponse = {\n roleNames: [],\n userIdentifier: payload.username,\n keyLifetimeSeconds: configSetup.keyLifetimeMinutes,\n userData: {},\n // We hard-code userInfo here, but you can add information that will be returned\n // to the authenticator in the response, along with the auth token.\n userInfo: {typeOfPerson: 'Cool'},\n // If you are writing an auth provider for use with the *admin* project,\n // then you will need to include the accountIdent in the userInfo, e.g.:\n // userInfo: {typeOfPerson: 'Cool', accountIdent: 1000},\n // If you know when and from where this user last logged in, you can\n // optionally return it here.\n lastLogin : {\n datetime: null,\n ipAddress : null\n }\n };\n\n // Set up the JNDI environment\n var Hashtable = Java.type(\"java.util.Hashtable\");\n var env = new Hashtable();\n env.put(\"java.naming.factory.initial\", \"com.sun.jndi.ldap.LdapCtxFactory\");\n env.put(\"java.naming.provider.url\", \"ldap://ldap.forumsys.com\");\n var userCN = \"uid=\" + payload.username + \",dc=example,dc=com\";\n env.put(\"java.naming.security.authentication\", \"simple\");\n env.put(\"java.naming.security.principal\", userCN);\n env.put(\"java.naming.security.credentials\", payload.password);\n env.put(\"java.naming.referral\", \"follow\");\n\n var InitialDirContext = Java.type(\"javax.naming.directory.InitialDirContext\");\n try {\n // First, can we connect? If not, then either the user is unknown,\n // or the password is wrong, and this will throw an exception.\n var ctx = null;\n\n try {\n ctx = new InitialDirContext(env);\n }\n catch (e) {\n return {\n errorMessage: \"Unable to authenticate with LDAP server: \" + e.getMessage()\n }\n }\n\n // Next, we retrieve the mail and phone attributes of the user, if present\n var attrs = ctx.getAttributes(userCN, [\"mail\", \"telephoneNumber\"]);\n var attrsEnum = attrs.getAll();\n while (attrsEnum.hasMore()) {\n var attrib = attrsEnum.next();\n authResponse.userData[attrib.getID()] = attrib.get().toString();\n }\n\n // If there are multi-valued attributes, this is how to retrieve them\n // attrs = ctx.getAttributes(userCN, [\"groups\"]);\n // attrsEnum = attrs.getAll();\n // if (attrsEnum.hasMore()) {\n // var mvAttr = attrsEnum.next();\n // var attrEnum = mvAttr.getAll();\n // while (attrEnum.hasMore()) {\n // var groupName = attrEnum.next();\n // // For example, we're only interested in groups starting with \"LAC-\"\n // if (groupName.startsWith(\"LAC-\")) {\n // authResponse.roleNames.push(groupName.substring(4));\n // }\n // }\n // }\n\n // Look for all the groups that contain our user. This is highly dependent\n // on your LDAP schema -- many schemas store the memberships in the users.\n var SearchControls = Java.type(\"javax.naming.directory.SearchControls\");\n var ctls = new SearchControls();\n ctls.setReturningAttributes([\"ou\"]);\n var answer = ctx.search(\"dc=example,dc=com\",\n \"(&(objectClass=groupOfUniqueNames)(uniqueMember=\" + userCN + \"))\", ctls);\n while (answer.hasMore()) {\n var groupName = answer.next().getAttributes().get(\"ou\").get();\n if (groupName == \"scientists\") {\n java.lang.System.out.println(\"User \" + payload.username +\n \" is a scientist and therefore gets full access.\");\n authResponse.roleNames.push(\"API Owner\");\n authResponse.roleNames.push(\"Full access\");\n }\n else if (groupName == \"mathematicians\") {\n java.lang.System.out.println(\"User \" + payload.username +\n \" is a mathematician and therefore gets read-only access.\");\n authResponse.roleNames.push(\"Read only\");\n }\n else {\n // Ignore other groups\n java.lang.System.out.println(\"Ignoring group: \" + groupName);\n }\n }\n\n if ( ! authResponse.roleNames.length) {\n java.lang.System.out.println(\"User \" + payload.username + \" gets no access\");\n return {\n errorMessage: \"User \" + payload.username +\n \" is neither a mathematician nor a scientist: access denied.\"\n }\n }\n }\n catch (e) {\n return {\n errorMessage: e.getMessage()\n }\n }\n\n return authResponse;\n };\n\n // getLoginInfo gets called to create the logon dialog - you can change this if your\n // authentication method does not use username/password, or if you don't like the names,\n // but of course you'll have to change the authenticate function correspondingly.\n result.getLoginInfo = function getLoginInfo() {\n return {\n fields: [\n {\n name: \"username\",\n display: \"User name\",\n description: \"Enter your Username, e.g. einstein\",\n type: \"text\",\n length: 40,\n helpURL: \"\"\n },\n {\n name: \"password\",\n display: \"Password\",\n description: \"Enter your password, e.g. password\",\n type: \"password\",\n length: 40,\n helpURL: \"\"\n }\n ],\n links : []\n };\n };\n\n // This function is called to determine what parameters can be configured in this auth provider.\n // The values are stored in the admin database when the user saves the auth provider.\n result.getConfigInfo = function getConfigInfo() {\n return {\n current : {\n \"serverName\": configSetup.serverName,\n \"keyLifetimeMinutes\" : configSetup.keyLifetimeMinutes\n },\n fields : [\n {\n name: \"serverName\",\n display: \"LDAP Server Name\",\n type: \"text\",\n length: 40,\n helpURL: \"\"\n },\n {\n name: \"keyLifetimeMinutes\",\n display: \"API Key Lifetime (Minutes)\",\n type: \"number\",\n length: 8,\n helpURL: \"\"\n }\n ],\n links: []\n };\n };\n\n return result;\n}\n",
"bootstrap_config_value": "create\n",
"param_map": "\"keyLifetimeMinutes\"=\"60\", \"serverName\"=\"ldap://localhost:389\"",
"get_config_info_code": null,
"configure_code": null,
"get_login_info_code": null,
"auth_code": null,
"account_ident": null
},
{
"name": "GatewayAuth",
"comments": null,
"auth_type_ident": 3,
"class_name": "com.kahuna.server.auth.HttpAuthProvider",
"javascript_authprovider_code": null,
"bootstrap_config_value": null,
"param_map": null,
"get_config_info_code": "var pkField = configInfo.addConfigField();\npkField.name = \"AuthPublicKeyText\";\npkField.description = \"The public key to verify incoming authentication. This can be either:\" +\n\t\t\"a JSON Web Key (JWK), which will start with something like { \\\"kty\\\": \\\"RSA\\\", etc...\" +\n\t\t\"an X.509 certificate, which will start with the line -----BEGIN CERTIFICATE-----,\" +\n\t\t\"or an X.509 public key, which will start with the line -----BEGIN PUBLIC KEY-----\";\npkField.display = \"Auth certificate/public key\";\npkField.length = 10000;\n\nvar pkAlgoField = configInfo.addConfigField();\npkAlgoField.name = \"AuthPublicKeyAlgorithm\";\npkAlgoField.description = \"Optional: the algorithm for the public key. If none is specified, RSA is assumed.\";\npkAlgoField.display = \"Auth public key algorithm\";\npkAlgoField.length = 20;\n\nvar jwtHeaderName = configInfo.addConfigField();\njwtHeaderName.name = \"AuthHeaderName\";\njwtHeaderName.description = \"Optional: name of HTTP header containing authentication, used for caching.\" +\n\t\t\" If this is not specified, no caching will occur, which will incur a small performance penalty (see docs for details)\";\njwtHeaderName.display = \"Auth Header Name\";\njwtHeaderName.length = 30;\n",
"configure_code": "for (var paramName in parameters) {\n log.info(\"Parameter \" + paramName +\n \" has value \" + parameters[paramName]);\n}\n",
"get_login_info_code": "loginInfo.loginStatus = \"Authentication is assumed to be done by the Gateway. Login is not allowed here.\";\n\t\n",
"auth_code": "var encodedJwt = servletRequest.getHeader(\"Authorization\");\nif ( ! encodedJwt || encodedJwt.trim().length === 0) {\n result.errorMessage = \"No Authorization header provided\";\n return;\n}\nif ( ! encodedJwt.startsWith(\"Bearer \")) {\n result.errorMessage = \"Authorization header does not have scheme Bearer\";\n return;\n}\nencodedJwt = encodedJwt.substring(\"Bearer \".length);\nvar Jwts = Java.type(\"io.jsonwebtoken.Jwts\");\n// Parse and validate the JWT\nvar jwtClaims = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(encodedJwt);\nresult.userIdentifier = jwtClaims.body.sub;\nresult.userData[\"name\"] = jwtClaims.body.name;\n/*\n * The data stored in userData object with e.g. key \"phoneNumber\" can be retrieved in rules,\n * events, functions, etc... with:\n * req.apiKey.getDataObjects().get(\"phoneNumber\");\n */\nvar groups = jwtClaims.body.groups;\nprint(\"result.userIdentifier:\" + result.userIdentifier +\n \" result.userData:\" + result.userData +\n \" groups:\" + groups ); // Outputs to console\nif (groups.indexOf('admin_staff') > -1) {\n result.roleNames.add(\"Full access\");\n}\nelse {\n result.errorMessage = \"Only managers can use this API\";\n}\n",
"account_ident": null
},
{
"name": "Built-in authentication",
"comments": null,
"auth_type_ident": 1,
"class_name": "com.kahuna.server.auth.db.DefaultAuthProvider",
"javascript_authprovider_code": null,
"bootstrap_config_value": null,
"param_map": "\"datasource\"=\"AdminDB\"",
"get_config_info_code": null,
"configure_code": null,
"get_login_info_code": null,
"auth_code": null,
"account_ident": null
}
]