/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.netbeans.modules.websvc.saas.codegen.php; import java.io.BufferedReader; import java.io.FileReader; import org.netbeans.modules.websvc.saas.codegen.*; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.netbeans.api.project.Project; import org.netbeans.modules.websvc.saas.codegen.Constants.DropFileType; import org.netbeans.modules.websvc.saas.codegen.Constants.HttpMethodType; import org.netbeans.modules.websvc.saas.codegen.Constants.SaasAuthenticationType; import org.netbeans.modules.websvc.saas.codegen.model.ParameterInfo; import org.netbeans.modules.websvc.saas.codegen.model.SaasBean.HttpBasicAuthentication; import org.netbeans.modules.websvc.saas.codegen.model.SaasBean.SessionKeyAuthentication; import org.netbeans.modules.websvc.saas.codegen.model.SaasBean.SaasAuthentication.UseTemplates; import org.netbeans.modules.websvc.saas.codegen.model.SaasBean.SaasAuthentication.UseTemplates.Template; import org.netbeans.modules.websvc.saas.codegen.model.SaasBean.SignedUrlAuthentication; import org.netbeans.modules.websvc.saas.codegen.model.SaasBean; import org.netbeans.modules.websvc.saas.codegen.model.SaasBean.Time; import org.netbeans.modules.websvc.saas.codegen.util.Util; import org.netbeans.modules.websvc.saas.model.wadl.Resource; import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObject; import org.openide.util.Exceptions; /** * Code generator for REST services wrapping WSDL-based web service. * * @author nam */ public class SaasClientPhpAuthenticationGenerator extends SaasClientAuthenticationGenerator { public static final String INDENT = " "; private FileObject saasAuthFile; private FileObject loginFile; private FileObject callbackFile; public SaasClientPhpAuthenticationGenerator(SaasBean bean, Project project) { super(bean, project); } /* * Insert this code before new "+Constants.REST_CONNECTION+"() */ public String getPreAuthenticationCode() { String methodBody = ""; SaasAuthenticationType authType = getBean().getAuthenticationType(); if (authType == SaasAuthenticationType.API_KEY) { methodBody += INDENT+"$apiKey = " + getBean().getAuthenticatorClassName() + "::getApiKey();"; } else if (authType == SaasAuthenticationType.SESSION_KEY) { SessionKeyAuthentication sessionKey = (SessionKeyAuthentication) getBean().getAuthentication(); methodBody += INDENT + getBean().getAuthenticatorClassName() + "::login(" + getLoginArguments() + ");\n"; List<ParameterInfo> signParams = sessionKey.getParameters(); String paramStr = ""; if (signParams != null && signParams.size() > 0) { paramStr = getSignParamDeclaration(getBean(), signParams, Collections.<ParameterInfo>emptyList()); } String sigName = sessionKey.getSigKeyName(); paramStr += INDENT+"$sign_params = array();\n"; for (ParameterInfo p : getBean().getInputParameters()) { if (p.getName().equals(sigName)) continue; paramStr += INDENT+"$sign_params[\"" + p.getName() + "\"] = $" + Util.getVariableName(p.getName()) + ";\n"; } paramStr += INDENT+"$" + Util.getVariableName(sigName) + " = " + getBean().getAuthenticatorClassName() + "::sign($sign_params);\n";//sig methodBody += paramStr; } else if (authType == SaasAuthenticationType.HTTP_BASIC) { methodBody += INDENT + getBean().getAuthenticatorClassName() + "::login(" + getLoginArguments() + ");\n"; } return methodBody; } /* * Insert this code after new "+Constants.REST_CONNECTION+"() */ public String getPostAuthenticationCode() { String methodBody = ""; SaasAuthenticationType authType = getBean().getAuthenticationType(); if (authType == SaasAuthenticationType.SIGNED_URL) { SignedUrlAuthentication signedUrl = (SignedUrlAuthentication) getBean().getAuthentication(); List<ParameterInfo> signParams = signedUrl.getParameters(); if (signParams != null && signParams.size() > 0) { String paramStr = getSignParamDeclaration(getBean(), signParams, getBean().getInputParameters()); paramStr += INDENT+"$sign_params = array();\n"; for (ParameterInfo p : signParams) { paramStr += INDENT+"$sign_params[\"" + p.getName() + "\"] = $" + Util.getVariableName(p.getName()) + ";\n"; } paramStr += INDENT+"$" +Util.getVariableName(signedUrl.getSigKeyName()) + " = " + getBean().getAuthenticatorClassName() + "::sign($sign_params);\n"; methodBody += paramStr; } } else if (authType == SaasAuthenticationType.HTTP_BASIC) { String serviceName = ""; try { serviceName = getSaasServiceFolder().getName(); } catch (IOException ex) { } methodBody += INDENT + "$username = "+getBean().getAuthenticatorClassName()+"::getSession(\"" + serviceName + "username\");\n"; methodBody += INDENT + "$password = "+getBean().getAuthenticatorClassName()+"::getSession(\"" + serviceName + "password\");\n"; methodBody += INDENT + "$conn->setAuthentication($username, $password);\n"; } return methodBody; } /** * Create Authenticator */ public void createAuthenticatorClass() throws IOException { FileObject targetFolder = getSaasServiceFolder(); if(!getBean().isUseTemplates()) { if(saasAuthFile == null) { String authFileName = getBean().getAuthenticatorClassName(); String authTemplate = null; SaasAuthenticationType authType = getBean().getAuthenticationType(); if (authType == SaasAuthenticationType.API_KEY || authType == SaasAuthenticationType.HTTP_BASIC || authType == SaasAuthenticationType.SIGNED_URL || authType == SaasAuthenticationType.SESSION_KEY) { authTemplate = SaasClientCodeGenerator.TEMPLATES_SAAS + getAuthenticationType().getClassIdentifier(); } if (authTemplate != null) { DataObject d = Util.createDataObjectFromTemplate( authTemplate + Constants.SERVICE_AUTHENTICATOR + "."+Constants.PHP_EXT, targetFolder, authFileName);// NOI18n if(d != null) saasAuthFile = d.getPrimaryFile(); } } } else { UseTemplates useTemplates = null; if(getBean().getAuthentication() instanceof SessionKeyAuthentication) { SessionKeyAuthentication sessionKey = (SessionKeyAuthentication) getBean().getAuthentication(); useTemplates = sessionKey.getUseTemplates(); } else if(getBean().getAuthentication() instanceof HttpBasicAuthentication) { HttpBasicAuthentication httpBasic = (HttpBasicAuthentication) getBean().getAuthentication(); useTemplates = httpBasic.getUseTemplates(); } if(useTemplates != null) { String dropType = getDropFileType().prefix(); for (Template template : useTemplates.getTemplates()) { if(!template.getDropTypeList().contains(dropType)) continue; String id = template.getId(); String type = template.getType(); String templateUrl = template.getUrl(); if (templateUrl.contains("Authenticator")) { String fileName = getBean().getAuthenticatorClassName(); FileObject fobj = targetFolder.getFileObject(fileName); if (fobj == null) { Util.createDataObjectFromTemplate(templateUrl, targetFolder, fileName); Map<String, String> tokens = new HashMap<String, String>(); tokens.put("__GROUP__", targetFolder.getName()); replaceTokens(targetFolder.getFileObject(fileName, Constants.PHP_EXT), tokens); } } } } } //Also copy config if(getBean().getAuthenticationType() != SaasAuthenticationType.PLAIN) { String profileName = getBean().getAuthenticatorClassName()+"Profile"; if (getAuthenticationProfile() != null && !getAuthenticationProfile().trim().equals("")) { try { Util.createDataObjectFromTemplate(getAuthenticationProfile(), targetFolder, profileName); } catch (Exception ex) { throw new IOException("Profile file specified in " + "saas-services/service-metadata/authentication/@profile, " + "not found: " + getAuthenticationProfile());// NOI18n } } } } /** * Create Authorization Frame */ public void createAuthorizationClasses() throws IOException { if (getBean().isDropTargetWeb()) { List<ParameterInfo> filterParams = getAuthenticatorMethodParameters(); final String[] parameters = Util.getGetParamNames(filterParams); final Object[] paramTypes = Util.getGetParamTypes(filterParams); createSessionKeyAuthorizationClassesForWeb( getBean(), getProject(), getBean().getSaasName(), getBean().getSaasServicePackageName(), getSaasServiceFolder(), loginFile, callbackFile, parameters, paramTypes, getBean().isUseTemplates(), getDropFileType() ); } } /** * Return target and generated file objects */ public void modifyAuthenticationClass() throws IOException { } /** * Return target and generated file objects */ public void modifyAuthenticationClass(final String comment, final Object[] modifiers, final Object returnType, final String name, final String[] parameters, final Object[] paramTypes, final Object[] throwList, final String bodyText) throws IOException { } public String getLoginBody(SaasBean bean, String groupName, String paramVariableName) throws IOException { if (getBean().isDropTargetWeb()) { if (getBean().getAuthenticationType() != SaasAuthenticationType.SESSION_KEY) { return null; } return Util.createSessionKeyLoginBodyForWeb(bean, groupName, paramVariableName); } String methodBody = ""; return methodBody; } public String getLogoutBody() { String methodBody = ""; return methodBody; } public String getTokenBody(SaasBean bean, String groupName, String paramVariableName, String saasServicePkgName) throws IOException { if (getBean().isDropTargetWeb()) { if (getBean().getAuthenticationType() != SaasAuthenticationType.SESSION_KEY) { return null; } return Util.createSessionKeyTokenBodyForWeb(bean, groupName, paramVariableName, saasServicePkgName); } String authFileName = getBean().getAuthorizationFrameClassName(); String methodBody = ""; return methodBody; } public String getSignParamUsage(List<ParameterInfo> signParams, String groupName) { return Util.getSignParamUsage(signParams, groupName, getBean().isDropTargetWeb()); } /* * Generates something like $apiKey = FacebookAuthenticator::getApiKey(); $sessionKey = FacebookAuthenticator::getSessionKey(); $method = "facebook.friends.get"; $v = "1.0"; $callId = RestConnection::currentTimeMillis(); */ public static String getSignParamDeclaration(SaasBean bean, List<ParameterInfo> signParams, List<ParameterInfo> filterParams) { String paramStr = ""; for (ParameterInfo p : signParams) { String[] pIds = getParamIds(p, bean.getSaasName(), bean.isDropTargetWeb()); if (pIds != null) {//process special case paramStr += INDENT+ "$" + Util.getVariableName(pIds[0]) + " = " + pIds[1] + ";\n"; continue; } if (Util.isContains(p, filterParams)) { continue; } paramStr += INDENT+ "$" + Util.getVariableName(p.getName()) + " = "; if (p.getFixed() != null) { paramStr += "\"" + p.getFixed() + "\";\n"; } else if (p.getType() == Date.class) { paramStr += "$conn->getDate();\n"; } else if (p.getType() == Time.class) { paramStr += "RestConnection::currentTimeMillis();\n"; } else if (p.getType() == HttpMethodType.class) { paramStr += "\"" + bean.getHttpMethod().value() + "\";\n"; } else if (p.isRequired()) { if (p.getDefaultValue() != null) { paramStr += getQuotedValue(p.getDefaultValue().toString()) + ";\n"; } else { paramStr += "\"\";\n"; } } else { if (p.getDefaultValue() != null) { paramStr += getQuotedValue(p.getDefaultValue().toString()) + ";\n"; } else { paramStr += "null;\n"; } } } paramStr += "\n"; return paramStr; } public static String getQuotedValue(String value) { StringBuffer sb = new StringBuffer(); String[] parts = value.replace("+", "+").split("+"); for(String part:parts) { if(isWord(part)) sb.append("$"+part.trim()+"."); else sb.append(part+"."); } String str = sb.toString(); if(parts.length > 0) str = str.substring(0, str.length()-1); return Util.getQuotedValue(str); } public static boolean isWord(String part) { if(part == null || part.trim().equals("")) return false; String word = part.trim(); for(char ch:word.toCharArray()) { if(!Character.isLetter(ch)) return false; } return true; } public static String[] getParamIds(ParameterInfo p, String groupName, boolean isDropTargetWeb) { if (p.getId() != null) {//process special case String[] pElems = p.getId().split("="); if (pElems.length == 2) { String val = pElems[1]; if (val.startsWith("{")) { val = val.substring(1); } if (val.endsWith("}")) { val = val.substring(0, val.length() - 1); } val = Util.getVariableName(val); val = Util.getAuthenticatorClassName(groupName) + "::" + "get" + val.substring(0, 1).toUpperCase() + val.substring(1); val += "()"; return new String[]{pElems[0], val}; } } return null; } public static void createSessionKeyAuthorizationClassesForWeb( SaasBean bean, Project project, String groupName, String saasServicePackageName, FileObject targetFolder, FileObject loginFile, FileObject callbackFile, final String[] parameters, final Object[] paramTypes, boolean isUseTemplates, DropFileType dropFileType) throws IOException { SaasAuthenticationType authType = bean.getAuthenticationType(); if (authType == SaasAuthenticationType.SESSION_KEY || authType == SaasAuthenticationType.HTTP_BASIC) { UseTemplates useTemplates = null; if (bean.getAuthentication() instanceof SessionKeyAuthentication) { SessionKeyAuthentication sessionKey = (SessionKeyAuthentication) bean.getAuthentication(); useTemplates = sessionKey.getUseTemplates(); } else if (bean.getAuthentication() instanceof HttpBasicAuthentication) { HttpBasicAuthentication httpBasic = (HttpBasicAuthentication) bean.getAuthentication(); useTemplates = httpBasic.getUseTemplates(); } if (useTemplates != null) { String dropType = dropFileType.prefix(); for (Template template : useTemplates.getTemplates()) { if (!template.getDropTypeList().contains(dropType)) { continue; } String id = template.getId(); String type = template.getType() == null ? "" : template.getType(); String templateUrl = template.getUrl(); if (templateUrl == null || templateUrl.trim().equals("")) { throw new IOException("Authentication template is empty."); } //FIXME - Hack if (templateUrl.contains("Desktop")) { continue; } String fileName = null; // if (type.equals(Constants.LOGIN)) { if (templateUrl.contains("Login")) { fileName = bean.getSaasName() + Util.upperFirstChar(Constants.LOGIN); // } else if (type.equals(Constants.CALLBACK)) { } else if (templateUrl.contains("Callback")) { fileName = bean.getSaasName() + Util.upperFirstChar(Constants.CALLBACK); } else if (templateUrl.contains("Authenticator")) { // } else if (type.equals(Constants.AUTH)) { continue; } FileObject fObj = null; if (fileName != null) { fObj = targetFolder.getFileObject(fileName); if (fObj == null) { DataObject d = Util.createDataObjectFromTemplate(templateUrl, targetFolder, fileName); if (d != null) { fObj = d.getPrimaryFile(); Map<String, String> tokens = new HashMap<String, String>(); tokens.put("__GROUP__", targetFolder.getName()); replaceTokens(targetFolder.getFileObject(fileName, Constants.PHP_EXT), tokens); } } } if (fObj != null) { if (type.equals(Constants.LOGIN)) { loginFile = fObj; } else if (type.equals(Constants.CALLBACK)) { callbackFile = fObj; } } } } } } private static void replaceTokens(FileObject fO, Map<String, String> tokens) throws IOException { FileLock lock = fO.lock(); try { BufferedReader reader = new BufferedReader(new FileReader(FileUtil.toFile(fO))); String line; StringBuffer sb = new StringBuffer(); while ((line = reader.readLine()) != null) { for(Map.Entry e:tokens.entrySet()) { String key = (String) e.getKey(); String value = (String) e.getValue(); line = line.replaceAll(key, value); } sb.append(line+"\n"); } OutputStreamWriter writer = new OutputStreamWriter(fO.getOutputStream(lock), "UTF-8"); try { writer.write(sb.toString()); } finally { writer.close(); } } finally { lock.releaseLock(); } } }