Skip to content

Commit 53a7fd5

Browse files
committed
initial check in
0 parents  commit 53a7fd5

18 files changed

+317
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.env
2+
private/

LICENSE

Whitespace-only changes.

Makefile

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
init:
2+
pip install -r requirements.txt
3+
4+
test:
5+
py.test tests

README.rst

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
Salesforce Micro Service
2+
========================
3+
4+
This project provides the middleware layer between Salesforce and custom built applications
5+
6+
Authentication
7+
==============
8+
9+
This package currently supports Username and Password and JWT Bearer Token Flow::
10+
11+
Update the .env with client credenitals for the grant type being used
12+
13+
Required values for Username and Password grant type:
14+
15+
::
16+
17+
SALESFORCE_OAUTH_CONSUMER_TOKEN
18+
SALESFORCE_OAUTH_CONSUMER_SECRET
19+
SALESFORCE_USER
20+
SALESFORCE_PASSWORD
21+
SALESFORCE_ACCESS_TOKEN_URL
22+
23+
Required values for JWT grant type:
24+
25+
::
26+
27+
SALESFORCE_OAUTH_CONSUMER_TOKEN
28+
SALESFORCE_CERTIFICATE
29+
SALESFORCE_USER
30+
SALESFORCE_PRIVATE_KEY
31+
32+

__init__.py

Whitespace-only changes.

__main__.py

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
def main():
2+
pass
3+
4+
if __name__ == "__main__":
5+
main()

requirements.txt

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
PyMySQL
2+
python-env
3+
dotenv==0.0.5
4+
simple-salesforce==0.69
5+
salesforce-oauth-request
6+
PyJWT
7+
cryptography
8+
pem
9+
pymongo

salesforce/.query.py.swo

12 KB
Binary file not shown.

salesforce/.query.py.swp

12 KB
Binary file not shown.

salesforce/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
## initialize the salesforce package
2+
from salesforce import *

salesforce/connect.py

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import os
2+
import time
3+
import jwt
4+
import pem
5+
import requests
6+
import json
7+
import base64
8+
from calendar import timegm
9+
from datetime import datetime, timedelta
10+
from simple_salesforce import Salesforce
11+
from os.path import join, dirname
12+
from dotenv import Dotenv
13+
14+
""" SalesForce Authentication """
15+
class SalesForceOAuth:
16+
17+
""" Sets up environment values for all grant types """
18+
def __init__(self):
19+
dotenv_path = Dotenv(join(dirname(__file__), '..', '.env'))
20+
os.environ.update(dotenv_path)
21+
22+
self.consumer_key = os.environ.get("SALESFORCE_OAUTH_CONSUMER_TOKEN")
23+
self.consumer_secret = os.environ.get("SALESFORCE_OAUTH_CONSUMER_SECRET")
24+
self.api_domain = os.environ.get("SALESFORCE_API_DOMAIN")
25+
self.access_token_url = os.environ.get("SALESFORCE_ACCESS_TOKEN_URL")
26+
self.username = os.environ.get("SALESFORCE_USER")
27+
self.password = os.environ.get("SALESFORCE_PASSWORD")
28+
29+
""" Determines OAuth Grant Type and runs method
30+
returns a dictionary consisinting of an instance_url and access_token
31+
"""
32+
def getAccessToken(self, grant_type):
33+
self.grant_type = grant_type
34+
if grant_type == 'password':
35+
token = self.passwordGrantType()
36+
elif grant_type == 'jwt':
37+
token = self.jwtGrantType()
38+
elif grant_type == 'web-server':
39+
self.webGrantType()
40+
else:
41+
pass
42+
43+
return token
44+
45+
""" Password Grant Type for user/server credentials
46+
need a client_id and client_secret
47+
returns a dictionary consisting of an instance_url and access_token
48+
used to make API calls
49+
"""
50+
def passwordGrantType(self):
51+
token = dict()
52+
headers = {
53+
'Content-Type': 'application/x-www-form-urlencoded'
54+
}
55+
56+
post_data = {'grant_type': self.grant_type,
57+
'client_id': self.consumer_key,
58+
'client_secret': self.consumer_secret,
59+
'username': self.username,
60+
'password': self.password }
61+
62+
result = requests.post(self.access_token_url, data=post_data, headers=headers)
63+
data = json.loads(result.text)
64+
access_token = data['access_token']
65+
instance_url = data['instance_url']
66+
token = { 'instance_url' : instance_url, 'access_token' : access_token }
67+
return token
68+
69+
""" JWT Token Grant Type - key based authentication
70+
returns a dictionary consisting of an instance_url and access_token
71+
used to make API calls
72+
"""
73+
def jwtGrantType(self):
74+
token = dict()
75+
certs = pem.parse_file(os.environ.get("SALESFORCE_CERTIFICATE"))
76+
certfile = os.environ.get("SALESFORCE_PRIVATE_KEY")
77+
78+
with open(certfile, "r") as my_cert_file:
79+
cert = my_cert_file.read()
80+
81+
payload = {
82+
'alg': 'RS256',
83+
'iss': self.consumer_key,
84+
'sub': self.username,
85+
'aud': 'https://login.salesforce.com',
86+
'exp': timegm(datetime.utcnow().utctimetuple())
87+
}
88+
pay_string = (str(payload))
89+
90+
encoded = jwt.encode(payload, cert, algorithm='RS256')
91+
headers = {
92+
'Content-Type': 'application/x-www-form-urlencoded'
93+
}
94+
grant_type = 'urn:ietf:params:oauth:grant-type:jwt-bearer'
95+
post_data = { 'grant_type': grant_type,
96+
'assertion': encoded
97+
}
98+
99+
result = requests.post(self.access_token_url, data=post_data, headers=headers)
100+
data = json.loads(result.text)
101+
access_token = data['access_token']
102+
instance_url = data['instance_url']
103+
token = { 'instance_url' : instance_url, 'access_token' : access_token }
104+
return token
105+
106+
107+
def webGrantType(self):
108+
pass
109+
110+
def decodeToken(self):
111+
pass
112+
##TODO:
113+
#public_key="private/public.key"
114+
#with open(pub_file, "r") as public_key:
115+
# pub = pub_file.read()
116+
#decoded = jwt.decode(encoded, pub, audience="https://login.salesforce.com")
117+
#print(decoded)
118+
119+
sf = SalesForceOAuth()
120+
##jwt_token = sf.getAccessToken('jwt')
121+
##print(jwt_token)
122+
password_token = sf.getAccessToken('password')
123+
print(password_token)
124+
125+
126+
127+
128+

salesforce/connect_test.py

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import unittest
2+
from connect import SalesForceOAuth
3+
4+
class TestSalesForceOAuth(unittest.TestCase):
5+
def __init__(self, grant_type):
6+
self.sf = SalesForceOAuth('password')
7+
8+
def test_salesforce_values(self):
9+
pass
10+
11+
12+
13+
14+
if __name__ == '__main__':
15+
unittest.main()

salesforce/mongo.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import os
2+
import json
3+
import pymongo
4+
5+
class MongoConnector:
6+
7+
def __init__():
8+
pass

salesforce/mongo_test.py

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import unittest
2+
from connect import SalesForceOAuth
3+
4+
class TestSalesForceOAuth(unittest.TestCase):
5+
def __init__(self, grant_type):
6+
self.sf = SalesForceOAuth('password')
7+
8+
def test_salesforce_values(self):
9+
pass
10+
11+
12+
13+
14+
if __name__ == '__main__':
15+
unittest.main()

salesforce/query.py

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import os
2+
import json
3+
from connect import SalesForceOAuth
4+
from simple_salesforce import Salesforce
5+
6+
class SalesForceQuery:
7+
def __init__(self, token):
8+
self.instance_url = token['instance_url']
9+
self.access_token = token['access_token']
10+
self.sf = Salesforce(instance_url=self.instance_url, session_id=self.access_token)
11+
12+
def getDataById(self, dataType, salesforce_id):
13+
data = self.sf.Contact.get(salesforce_id)
14+
##data = sf.(dataType).get(salesforce_id)
15+
##print(data)
16+
17+
def getDataByCustomField(self, dataType, custom_field):
18+
contact = self.sf.Contact.get_by_custom_id('My_Custom_ID__c', '22')
19+
pass
20+
21+
def getDataByQuery(self, query):
22+
data = self.sf.query(query)
23+
return data
24+
25+
def getDataByDateRange(self, dataType, date_range):
26+
pass
27+
28+
def getObjectMetaData(self, obj):
29+
metadata = self.sf.Contact.metadata()
30+
##print(metadata)
31+
32+
def describeObject(self, salesforce_obj):
33+
data = self.sf.Account.describe()
34+
return data
35+
36+
def sfObjectToJson(self, data):
37+
json_data = json.dumps(data)
38+
return json_data
39+
40+
def getObjectType(self, salesforce_obj_type):
41+
return {
42+
'Contact' : 'self.sf.Contact',
43+
'Account' : 'self.sf.Account'
44+
}[salesforce_obj_type]
45+
46+
47+
sf = SalesForceOAuth()
48+
token = sf.getAccessToken('password')
49+
salesforce_id = '0031a00000VG4mK'
50+
dataType = 'Contact'
51+
sfq = SalesForceQuery(token)
52+
sfq.getDataById(dataType, salesforce_id)
53+
##data = sfq.getDataByQuery("SELECT Id, Email FROM Contact WHERE LastName = 'Schweitzer'")
54+
salesforce_obj = 'Contact'
55+
data = sfq.describeObject(salesforce_obj)
56+
for field in data['fields']:
57+
print(field['name'])
58+
59+
60+

salesforce/query_test.py

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import unittest
2+
from connect import SalesForceQuery
3+
4+
class TestSalesForceQuery(unittest.TestCase):
5+
def __init__(self, grant_type):
6+
self.sf = SalesForceOAuth('password')
7+
8+
def test_salesforce_query(self):
9+
pass
10+
11+
12+
13+
14+
if __name__ == '__main__':
15+
unittest.main()

salesforce/sf_objects.py

Whitespace-only changes.

setup.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from setuptools import setup, find_packages
4+
5+
with open('README.rst') as f:
6+
readme = f.read()
7+
8+
with open('LICENSE') as f:
9+
license = f.read()
10+
11+
setup(
12+
name='salesforce microservice',
13+
version='0.0.1',
14+
description='Middleware application between Salesforce and custom built Progyny projects',
15+
long_description=readme,
16+
author='Walter Schweitzer',
17+
author_email='[email protected]',
18+
url='https://github.com/waltertschwe/python-salesforce-oauth',
19+
license=license,
20+
packages=find_packages(exclude=('docs'))
21+
)

0 commit comments

Comments
 (0)