• NathanS
  • NEWBIE
  • 5 Points
  • Member since 2007

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 0
    Questions
  • 7
    Replies

There is lots of good information on developer.force.com about SSO and Salesforce as the service provider but I can't find any information on using Salesforce as the identity provider to another service. I would like to be able to use my salesforce user and contact objects as my identity store for an outside application. Can it be done? Do I have to role my own SAML SSO service within Salesforce to get the job done? What kind of license agreement issues would I have to deal with?

 

Any thoughts?

  • August 02, 2010
  • Like
  • 1
I have developed a web service in java and then tried to crate an apex client to invoke my web service, but I have encountered the following problems:

1) In my wsdl a have a class hierarchy likes this:
<complexType name="Column1">
                <complexContent>
                    <extension base="sns:Column">
                        ......
                    </extension>
                </complexContent>
            </complexType>
When generating classes using wsdl2apex, there is no relation between Column1 and Column.
When generating java classes from the same wsdl Column1 extends Column.
Why wsdl2apex doesn’t generate the relation between Column1 and Column? 2)I have generated  apex classes from wsdl, and then I have manually put  extends(Column1 extends Column) public virtual class Column {        public  String name;       ……….. } public class Column1 extends Column{   public Integer length;    ……………………………………………………………….}  the service method should return an object witch contains a list of columns Structure getStructure(){Return an object  of type Column[] } If some of the elements of Column[] object, returned when invoking the web service  are  Of type Column1,  an error occurs : :58:20.883|FATAL_ERROR|System.CalloutException: Web service callout failed: Unable to parse callout response. Apex type not found for element =length I wanted to obtain the list of columns and then cast them to the specific subclass.  3)If in my wsdl I have the type "xsd:anyType" , when trying to generate apex classes using wsdl2apex the following message is displayed:

Error message:
Error: Unsupported schema type: {http://www.w3.org/2001/XMLSchema}anyType

Is there a work-around for this? 
ok, here's my class (work in progress)

Code:
//version 1.1
global class productEmailCreateCase implements Messaging.InboundEmailHandler {

global Messaging.InboundEmailResult
handleInboundEmail(Messaging.inboundEmail email,
Messaging.InboundEnvelope env){

// Create an inboundEmailResult object for returning
// the result of the Force.com Email Service
Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();

//define your debugging email
string debugEmail = 'youremail@domain.com';

// get contents of email
string subject = email.subject;
string myPlainText = email.plainTextBody;
string emailtype = 'new';
string fromname = email.fromname;
string fromemail = email.fromaddress;
string[] toemail = email.toaddresses;
string product = '';

//print debug info
system.debug('\n\nTo: ' + toemail + '\n' + 'From: ' + fromemail + '\nSubject\n' + subject + '\nBody\n' + myPlainText);

//set the product based on the incoming email
if (toemail != null){
for (string i : toemail){
if (i.contains('logmeinfree')){
product = 'LogMeIn Free';
}else if (i.contains('logmeinpro')){
product = 'LogMeIn Pro';
}else if (i.contains('logmeinitreach')){
product = 'LogMeIn IT Reach';
}else if (i.contains('logmeinrescue')){
product = 'LogMeIn Rescue';
}else if (i.contains('logmeinbackup')){
product = 'LogMeIn Backup';
}else if (i.contains('logmeinhamachi')){
product = 'LogMeIn Hamachi';
}else if (i.contains('remotelyanywhere')){
product = 'RemotelyAnywhere';
}else if (i.contains('networkconsole')){
product = 'Network Console';
}else if (i.contains('logmeinignition')){
product = 'LogMeIn Ignition';
}
}
}

// First, instantiate a new Pattern object "MyPattern"
Pattern MyPattern = Pattern.compile('.*—[:]{3}[a-z0-9A-Z]{15}[:]{3}.*–');

// Then instantiate a new Matcher object "MyMatcher"
Matcher MyMatcher = MyPattern.matcher(myPlainText);

//status of the matcher
boolean reply = MyMatcher.find();
system.debug('Reply: ' + reply);

//regexp for finding caseid \[:[a-zA-Z0-9]{18}:]
//boolean reply = pattern.matches(':::[a-zA-Z0-9]{18}:::', myPlainText);

//determine if this is a new case or a reply to an existing one
if(reply == true){
emailtype = 'reply';
}

if(emailtype == 'new'){
// new Case object to be created
Case[] newCase = new Case[0];

// Try to lookup any contacts based on the email from address
// If there is more than 1 contact with the same email address
// an exception will be thrown and the catch statement will be called
try {
// Add a new Case to the contact record we just found above
newCase.add(new Case(Description = myPlainText,
Subject = subject,
Origin = 'Email',
SuppliedEmail = email.fromAddress,
Product__c = product,
SuppliedName = email.fromName));

// Insert the new Case and it will be created and appended to the contact record
insert newCase;
System.debug('New Case Object: ' + newCase );
}
// If there is an exception with the query looking up
// the contact this QueryException will be called.
// and the exception will be written to the Apex Debug logs

catch (Exception e) {
System.debug('\n\nError:: ' + e + '\n\n');
string body = 'Message: ' + e.getMessage() + '\n' + e.getCause() + '\n\n' + email.subject + '\n' + fromemail + '\n' + fromname + '\n' + toemail;
sendDebugEmail(body, 'reply');
}
}else if (emailtype == 'reply') { //reply handling
// new Case object to be created
Task[] newTask = new Task[0];
//get the WhatId
string match = MyMatcher.group(0);
system.debug('Match String: ' + match);
string caseId = match.replaceall(':','').trim();
system.debug('Case ID: ' + caseId);

Case[] getCase = new Case[0];
getCase = [select casenumber, id from case where id = :caseId limit 1];


// Try to lookup any contacts based on the email from address
// If there is more than 1 contact with the same email address
// an exception will be thrown and the catch statement will be called
try {
// Add a new Case to the contact record we just found above
newTask.add(new Task(Description = myPlainText,
Subject = subject,
Status = 'Completed',
WhatId = caseId));

// Insert the new Case and it will be created and appended to the contact record
insert newTask;
getCase[0].Status = 'Reply from Customer';
update getCase[0];
System.debug('New Case Object: ' + newTask );
}
// If there is an exception with the query looking up
// the contact this QueryException will be called.
// and the exception will be written to the Apex Debug logs

catch (Exception e) {
System.debug('\n\nError:: ' + e + '\n\n');

//set up and send debug email
string body = 'Message: ' + e.getMessage() + '\n' + e.getCause() + '\n\n' + email.subject + '\n' + fromemail + '\n' + fromname + '\n' + toemail + '\nCase ID: ' + caseid;
sendDebugEmail(body, 'reply');
}

// Set the result to true, no need to send an email back to the user
// with an error message
}
result.success = true;

// Return the result for the Force.com Email Service
return result;
}

static testMethod void testCases1() {

// Create a new email and envelope object
Messaging.InboundEmail email = new Messaging.InboundEmail();
Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();

email.plainTextBody = 'Here is my plainText body of the email';
email.fromAddress =debugEmail;
email.subject = 'My test subject';

productEmailCreateCase caseObj = new productEmailCreateCase();
caseObj.handleInboundEmail(email, env);

// Create a new email and envelope object
Messaging.InboundEmail emailReply = new Messaging.InboundEmail();
Messaging.InboundEnvelope envReply = new Messaging.InboundEnvelope();

// Create the plainTextBody and fromAddres for the test
emailReply.plainTextBody = 'Here is my plainText body of the email';
emailReply.fromAddress = debugEmail;
emailReply.Subject = 'Re: LogMeIn Pro Case:00001030 - testing reply';

productEmailCreateCase caseReplyObj = new productEmailCreateCase();
caseReplyObj.handleInboundEmail(emailReply, envReply);

}
static testMethod void testCases2() {

// Create a new email and envelope object
Messaging.InboundEmail email = new Messaging.InboundEmail();
Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();

// Create the plainTextBody and fromAddres for the test
email.plainTextBody = 'Here is my plainText body of the email';
email.fromAddress ='some@email.com';
email.subject = 'My test subject';

productEmailCreateCase caseObj = new productEmailCreateCase();
caseObj.handleInboundEmail(email, env);

// Create a new email and envelope object
Messaging.InboundEmail emailReply = new Messaging.InboundEmail();
Messaging.InboundEnvelope envReply = new Messaging.InboundEnvelope();

// Create the plainTextBody and fromAddress for the test
emailReply.plainTextBody = 'Here is my plainText body of the email';
emailReply.fromAddress ='some@email.com';
emailReply.Subject = 'Re: LogMeIn Pro Case:00001030 - testing reply';

productEmailCreateCase caseReplyObj = new productEmailCreateCase();
caseReplyObj.handleInboundEmail(emailReply, envReply);
}

public void sendDebugEmail(string emailbody, string emailtype){
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] {'some@email.com'};
mail.setToAddresses(toAddresses);
mail.setSenderDisplayName('Salesforce Error Handling');
mail.setSubject('Error handling inbound email as a ' + emailtype);
mail.setPlainTextBody(emailbody);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}

static testMethod void testCases3() {

// Create a new email and envelope object
Messaging.InboundEmail email = new Messaging.InboundEmail();
Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();

// Create the plainTextBody and fromAddres for the test
string[] to = new List<string>();
to.add('logmeinfree@salesforce.com');
to.add('logmeinpro@salesforce.com');
to.add('logmeinitreach@salesforce.com');
to.add('logmeinrescue@salesforce.com');
to.add('logmeinbackup@salesforce.com');
to.add('logmeinhamachi@salesforce.com');
to.add('logmeinignition@salesforce.com');
to.add('remotelyanywhere@salesforce.com');
to.add('networkconsole@salesforce.com');
email.plainTextBody = 'This is my test body.';
email.fromAddress ='some@email.com';
email.subject = 'My test subject';
email.toaddresses = to;

productEmailCreateCase caseObj = new productEmailCreateCase();
caseObj.handleInboundEmail(email, env);

// Create a new email and envelope object
Messaging.InboundEmail emailReply = new Messaging.InboundEmail();
Messaging.InboundEnvelope envReply = new Messaging.InboundEnvelope();

// Create the plainTextBody and fromAddres for the test
emailReply.plainTextBody = ':::500700000059WZP:::';
emailReply.fromAddress ='some@email.com';
emailReply.Subject = 'Re: LogMeIn Pro Case:00001030 - testing reply';

productEmailCreateCase caseReplyObj = new productEmailCreateCase();
caseReplyObj.handleInboundEmail(emailReply, envReply);
}

static testMethod void testEmail(){
productEmailCreateCase obj = new productEmailCreateCase();
obj.sendDebugEmail('this is the body', 'new');
}
}

 
you can modify to suit your own needs, as there's 'some' custom stuff particular to our org.  this email class handles both new inbound and reply inbound emails.

a couple notes:
* you need to DELIVER emails to the SF address you associate with the email service.  you cannot just forward them.  this means, you need to be able to have your email server/service deliver to the address directly.  if you don't, you'll lose contact info, which would be mapped to the webname and web email fields.
* contact autocreation is not in this revision, as I use a custom s-control for this now.  i'm open to ideas on what exactly should be done on this front.  we currently create a contact, and map it to an account based on the domain part of the email address.  i'm not interested in coding a solution to handle person accounts.
* you need to modify the 'debugEmail' value to be the one you want errors sent to.  rather than relying on the debug logs of SF, i figured this would be an easier approach.
* code coverage is 90%.  the only code that isn't covered is the catch statement exception handling, as I didn't know how to force an exception at the time I wrote this.
* you need to add the following to the bottom of all your email templates, on a line of its own.
Code:
:::{!case.id}:::

 
i'm open to feedback of course.



Message Edited by paul-lmi on 03-10-2008 09:57 AM