├── .Rbuildignore ├── data └── testKey.rda ├── .gitignore ├── tests ├── run_tests.R └── tests │ └── 1.R ├── RMauthClient.Rproj ├── NAMESPACE ├── DESCRIPTION ├── LICENSE.txt ├── man ├── RMauthClient.Rd ├── composeMAuthHeader.Rd ├── makeMAuthCall.Rd └── RMauthClient-package.Rd ├── examples └── exampleUse.R ├── R └── RMauthClient.R └── README.md /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^.*\Config\.*$ 4 | ^examples$ -------------------------------------------------------------------------------- /data/testKey.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdsol/RMauthClient/develop/data/testKey.rda -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | R/Config/*.json 5 | R/Config/*.pem 6 | R/Config/*.txt 7 | R/Config/*.yml 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /tests/run_tests.R: -------------------------------------------------------------------------------- 1 | library(RUnit) 2 | library(RMauthClient) 3 | 4 | test.suite <- defineTestSuite("RMauthClient", 5 | dirs = file.path("tests"), 6 | testFileRegexp = '^\\d+\\.R') 7 | 8 | test.result <- runTestSuite(test.suite) 9 | 10 | printTextProtocol(test.result) 11 | -------------------------------------------------------------------------------- /RMauthClient.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.1 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | BuildType: Package 16 | PackageUseDevtools: Yes 17 | PackageInstallArgs: --no-multiarch --with-keep.source 18 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | export(RMauthClient) 2 | export(composeMAuthHeader) 3 | export(makeMAuthCall) 4 | 5 | importFrom(httr, add_headers) 6 | importFrom(httr, content) 7 | importFrom(httr, GET) 8 | importFrom(httr, POST) 9 | importFrom(httr, RETRY) 10 | importFrom(httr, DELETE) 11 | 12 | importFrom(jsonlite, fromJSON) 13 | 14 | importFrom(methods, new) 15 | 16 | importFrom(openssl, base64_encode) 17 | importFrom(openssl, sha512) 18 | 19 | importFrom(PKI, PKI.load.key) 20 | importFrom(PKI, PKI.pencrypt) 21 | 22 | importFrom(stats, setNames) 23 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: RMauthClient 2 | Type: Package 3 | Title: RMauthClient 4 | Version: 1.1 5 | Date: 2015-03-03 6 | Author: Pramod Somashekar 7 | Maintainer: Justin Thomson 8 | Depends: 9 | R (>= 2.10) 10 | Imports: 11 | httr, 12 | jsonlite, 13 | methods, 14 | openssl, 15 | PKI 16 | Suggests: 17 | RUnit 18 | Remotes: 19 | github::mdsol/PKI 20 | Description: This is an MAuth v1 client for R. It can enable you to get and post requests via MAuth.... 21 | License: MIT + LICENSE 22 | RoxygenNote: 7.0.2 23 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Medidata Solutions 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /man/RMauthClient.Rd: -------------------------------------------------------------------------------- 1 | \name{RMauthClient} 2 | \alias{RMauthClient} 3 | \title{ 4 | RMauthClient 5 | } 6 | \description{ 7 | \code{RMauthClient} initializes an RMauthClient object, which can be used to 8 | pass to \code{makeMAuthCall} to make an MAuth call. 9 | } 10 | \usage{ 11 | RMauthClient(app_uuid=NULL, mauth_base_url=NULL, mauth_api_version="v1", 12 | private_key=NULL) 13 | } 14 | \arguments{ 15 | \item{app_uuid}{A valid application uuid which has been pre-registered with a 16 | valid mauth instance you are making requests to} 17 | \item{mauth_base_url}{The base url of the mauth instance your app_uuid and 18 | keys are registered with} 19 | \item{mauth_api_version}{Should be v1, but if its something else, please 20 | specify it.} 21 | \item{private_key}{Your private key, in pem format, as a string Note: IT 22 | SHOULD BE A CHARACTER VECTOR, one item per line of the keyfile (see example 23 | usage file)} 24 | } 25 | %\details{ 26 | %} 27 | \value{ 28 | RMAuthClient object 29 | } 30 | %\references{ 31 | %} 32 | \author{ 33 | Pramod Somashekar 34 | } 35 | %\note{ 36 | %} 37 | \seealso{ 38 | \code{\link{RMauthClient-package}} 39 | } 40 | \examples{ 41 | data(testKey) 42 | 43 | c <- RMauthClient(app_uuid="aaabbbcc-dddd-abcd-abcd-eff6b4b0b637", 44 | mauth_base_url="https://mauth-sandbox.imedidata.net", 45 | private_key=testKey) 46 | } -------------------------------------------------------------------------------- /man/composeMAuthHeader.Rd: -------------------------------------------------------------------------------- 1 | \name{composeMAuthHeader} 2 | \alias{composeMAuthHeader} 3 | \title{ 4 | composeMAuthHeader 5 | } 6 | \description{ 7 | \code{composeMAuthHeader} will compose the elements of a header which can be used to call MAuth v1. 8 | } 9 | \usage{ 10 | composeMAuthHeader(RMauthClientObject, method, base_url, route, body="") 11 | } 12 | \arguments{ 13 | \item{RMauthClientObject}{Valid RMauthClient object.} 14 | \item{method}{either "GET", "POST", "PUT" or "DELETE"} 15 | \item{base_url}{base url of the service you are calling} 16 | \item{route}{the route of the service you want to get a response from} 17 | \item{body}{Body of the request, ie. for POST requests. (Optional)} 18 | 19 | } 20 | %\details{ 21 | %} 22 | \value{ 23 | Number of values, which you can access for the different headers. 24 | } 25 | %\references{ 26 | %} 27 | \author{ 28 | Pramod Somashekar 29 | } 30 | %\note{ 31 | %} 32 | \seealso{ 33 | \code{\link{RMauthClient-package}} 34 | } 35 | \examples{ 36 | data(testKey) 37 | 38 | c <- RMauthClient(app_uuid="aaabbbcc-dddd-abcd-abcd-eff6b4b0b637", 39 | mauth_base_url="https://mauth-sandbox.imedidata.net", 40 | private_key=testKey) 41 | 42 | headers<-composeMAuthHeader(c, 43 | "GET", 44 | "https://eureka-sandbox.imedidata.net", 45 | "/v1/apis", 46 | "") 47 | } -------------------------------------------------------------------------------- /man/makeMAuthCall.Rd: -------------------------------------------------------------------------------- 1 | \name{makeMAuthCall} 2 | \alias{makeMAuthCall} 3 | \title{ 4 | makeMAuthCall 5 | } 6 | \description{ 7 | \code{makeMAuthCall} will make a call to MAuth v1 and return a response, which you must deal with on your own. 8 | } 9 | \usage{ 10 | makeMAuthCall(RMauthClientObject, method, base_url, route, body="") 11 | } 12 | \arguments{ 13 | \item{RMauthClientObject}{Valid RMauthClient object.} 14 | \item{method}{either "GET", "POST", "PUT" or "DELETE"} 15 | \item{base_url}{base url of the service you are calling} 16 | \item{route}{the route of the service you want to get a response from} 17 | \item{queryString}{optional query string value} 18 | \item{retryAttempts}{optional number of attempts to retry request before returning non-200 response} 19 | \item{body}{Body of the request, ie. for POST requests.} 20 | \item{header_overrides}{any additional headers or overrides (ie. Content-Type) in a named list} 21 | 22 | } 23 | %\details{ 24 | %} 25 | \value{ 26 | Response (likely in json, depending on the service.) 27 | } 28 | %\references{ 29 | %} 30 | \author{ 31 | Pramod Somashekar 32 | } 33 | %\note{ 34 | %} 35 | \seealso{ 36 | \code{\link{RMauthClient-package}} 37 | } 38 | \examples{ 39 | data(testKey) 40 | 41 | c <- RMauthClient(app_uuid="aaabbbcc-dddd-abcd-abcd-eff6b4b0b637", 42 | mauth_base_url="https://mauth-sandbox.imedidata.net", 43 | private_key=testKey) 44 | 45 | response<-makeMAuthCall(c, 46 | "GET", 47 | "https://eureka-sandbox.imedidata.net", 48 | "/v1/apis", 49 | "") 50 | } -------------------------------------------------------------------------------- /man/RMauthClient-package.Rd: -------------------------------------------------------------------------------- 1 | \name{RMauthClient-package} 2 | \alias{RMauthClient-package} 3 | \docType{package} 4 | \title{ 5 | RMauthClient 6 | } 7 | \description{ 8 | This simple library can enable you to post and get requests via MAuth v1 in R. It should return back to you a valid response after authorization, which you will have to interpret on your own. 9 | } 10 | \details{ 11 | \tabular{ll}{ 12 | Package: \tab RMauthClient\cr 13 | Type: \tab Package\cr 14 | Version: \tab 1.0\cr 15 | Date: \tab 2015-03-03\cr 16 | License: \tab MIT + file LICENSE\cr 17 | } 18 | Usage is really simple. 19 | Simply create an MAuthClient object, and then call makeMAuthCall with the appropriate parameters. 20 | 21 | You will need a valid configuration for MAuth, passed in as the parameters when initializing RMauthClient. 22 | 23 | The private key, must be a 2048 bit RSA key for which the public key already has been registered with a valid MAuth v1 service. 24 | 25 | } 26 | \author{ 27 | Pramod Somashekar 28 | 29 | Maintainer: Pramod Somashekar 30 | } 31 | \references{ 32 | } 33 | \keyword{ package } 34 | \seealso{ 35 | } 36 | \examples{ 37 | library(httr) 38 | library(jsonlite) 39 | data(testKey) 40 | 41 | c <- RMauthClient(app_uuid="aaabbbcc-dddd-abcd-abcd-eff6b4b0b637", 42 | mauth_base_url="https://mauth-sandbox.imedidata.net", 43 | private_key=testKey) 44 | response <- makeMAuthCall(c, 45 | "GET", 46 | "https://eureka-sandbox.imedidata.net", 47 | "/v1/apis", 48 | "") 49 | f <- fromJSON(content(response, "text")) #f is now a valid frame. 50 | 51 | } 52 | -------------------------------------------------------------------------------- /examples/exampleUse.R: -------------------------------------------------------------------------------- 1 | #this is a basic example of how the R Mauth Client can be utilized.... 2 | library(base64enc) 3 | library(httr) 4 | library(openssl) 5 | library(PKI) 6 | library(RMauthClient) 7 | 8 | #Step 0: initialize your Mauth Client Configuration: 9 | key<-as.vector(strsplit("-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAqdxoaxAlVjs4f+TITZNmOhxv1Os6Wh7pghAt5IiFlMaEDXt4\nH8OvW/uww7McPtZ3oY1BpRW1w3Xbg7tQZX9fq8qHBBeXP8ZNMLILRkQu19neqwEJ\nGNGIIArv6coPTPMCntUvDcHT/yv8MKOPi9ArtgSxEdcOqqlP/IMUud6Rmp+19Wn8\nbJdzErwDsdHrgf/Luj2fDqbDbdnnKYWUyEHKmYylqC+oox53Hld6w0+9COu9Evwj\n3ThM3GKRUxyCQ+YYqAaCcROtAwbzqOiVCiHmqcXs3iE5qdYr53/SKtW8bd2nShjj\nRMAFa5QGaaRBzu5/HKFnH4xzI32JUcsVuS0+DQIDAQABAoIBADZrCnjiX1PU/TDc\nFt/jjSio25sXEUa2CJFGpa1Fn6YeQ0geekmS46dQZz0LMM1g4Eq9en5tCiJoq770\nT7l0qS3cYI0LEcW4vhoPsFT+mxNEFXYrisKMvlOlrV71ARnh8MD6A20g384sRUs/\n20krlBVoQ2I3x9cdDycSx50UlQk4A6ntnrtYnsduu1t8t3N9oZWh3sIaDdEtKR4C\nbsoM73mLh8VBADYhS3f+NtOKEsb8R80zWHVOdXe7EVRScE5YlPNKNpJv/Xl6k2Sw\nj2n3axReiPkgWyOFEjqvUIylDkodj8WdsFZ8U7nj0andfoHlytv+PY00JyZLHo0R\n1EA6b3ECgYEA3obMW9AixBEPKjiH6qxB6BDIZkrkptffESl0n0tTm+cBeFNDgGRW\nLDE4bogbY3eO2YzycS5TkFL0KeWBw+wZ05Je+/hK0/jhEkjWCe5Pfo3CiHNpj7ig\nBjGzcltqZq71+BzTvx18brgxtvRrjR1WM4dFCIQvcLBv0IYAUmIv3SMCgYEAw2mH\nIsUKlJJo4JE8Hc1v/RSp48478W7Hvpmm+CoeyefpVpUlDinK26nYZIjWVuvYS2/b\nfc6oIPqS67P662YORA/cXtyWhFrdGmXT9/vkGQ3NF/KgZZEIO3cPTDRnpC4ObzL1\nYGI4ZKJqzVDZNREiTvnEba8YSWG2UEbvRs1Gow8CgYAiImFUsB+1HbzKyDMpL1VI\nyNJExrY+VZzVIBvQl5hysMPL9lHDbyC81KwIYH57CoryGinSbL3KxL7JcnguWpg3\nmRtS4WpxC5tS17NlgJXXHt25WqLVtgduC8+v+g/fQnVeouVkSpycy0ps+x9IXTis\n3NIdFVHFonr0bKm9+WvIKwKBgCYmpS6Bn7Yv+2/UixMad8HGVgDW09coFLE+mF2d\nA5PRxjmUNr7UI/nM6CWAnbAsrXbU6NpgDW0a3rJL2mURuolJO3H9yRkgEEjGFqM0\nt2y4yBDj2rLZpOzPKtpq5M0l/MVzAnsF0hK7rvRU04NLzBH1K4dqhuhUvl5f6vk8\nvIy7AoGAQepXAvpDPKVIfxEJbxTKDocCbEuhG50NAmfyhqo0T4OlYCWzs5xtCwQF\n3Fe/7tI+askxPTMk9NzxqmWXx+3Fe6vSn8vRPELKpcQ0bNFxZh+oXT3SS1QbNOaF\nNQZbJH8EA9PppYKYlMo9xS+2AFsSC16h2OYO3P7XH/zg3ooIFzc=\n-----END RSA PRIVATE KEY-----", '\n'))[[1]] 10 | myMauthClient<- RMauthClient(app_uuid="12345678-4599-47db-b57d-b6e750596500", 11 | mauth_base_url="https://mauth-sandbox.imedidata.net", 12 | private_key=key) 13 | #Step 1: make the call 14 | response<-makeMAuthCall(myMauthClient, "GET", "https://eureka-sandbox.imedidata.net", "/v1/apis", "") 15 | 16 | #Step 2: get response text out 17 | content(response, "text") -------------------------------------------------------------------------------- /tests/tests/1.R: -------------------------------------------------------------------------------- 1 | library(RMauthClient) 2 | library(openssl) 3 | # 4 | 5 | data(testKey) 6 | 7 | test.RMAuthClientHeaderCompositionEncodingAndConfigLoad<-function() 8 | { 9 | #setup 10 | mauth_base_url<-"https://mauth-sandbox.imedidata.net" 11 | mauth_api_version<-"v1" 12 | app_uuid<- "aaabbbcc-dddd-abcd-abcd-eff6b4b0b637" 13 | c<-RMauthClient(mauth_base_url = mauth_base_url, mauth_api_version = mauth_api_version, app_uuid = app_uuid, private_key = testKey) 14 | 15 | generate_padding<-function(hashed_bin, keylength) 16 | { 17 | padding_length=keylength-length(hashed_bin)-3 18 | as.raw(c(0x00,0x01, rep(0xff, padding_length),0x00,hashed_bin)) 19 | } 20 | 21 | #prechecks 22 | 23 | #it should have loaded the key properly 24 | checkTrue("-----BEGIN RSA PRIVATE KEY-----" %in% c@private_key[[1]]) 25 | 26 | #it should have loaded the rest of the config properly 27 | checkTrue(c@mauth_base_url=="https://mauth-sandbox.imedidata.net" && 28 | c@mauth_api_version=="v1" && 29 | c@app_uuid=="aaabbbcc-dddd-abcd-abcd-eff6b4b0b637") 30 | 31 | 32 | #testing 33 | headerVal<-composeMAuthHeader(c, "GET", "https://mdsol.com", "/api/v1/tests", "") 34 | 35 | #it should contain the following headers 36 | checkTrue(all(names(headerVal) %in% c("X-MWS-Authentication","X-MWS-Time","Content-Type"))) 37 | 38 | #it should have the following for content type 39 | checkEquals(headerVal$`Content-Type`,"application/json;charset=utf-8") 40 | 41 | #it should have base64 encoded the message in the following way 42 | checkTrue( 43 | paste("MWS ", c@app_uuid, ":", 44 | base64_encode( 45 | PKI.pencrypt(generate_padding(charToRaw(sha512(paste("GET\n/api/v1/tests\n\n",c@app_uuid,"\n",headerVal$`X-MWS-Time`,sep = ""))),256), 46 | key=PKI.load.key(testKey,format = "PEM", private = T)) 47 | ),sep="")== 48 | headerVal$`X-MWS-Authentication` 49 | ) 50 | 51 | } 52 | 53 | test.RMAuthClientStops<-function() 54 | { 55 | #setup 56 | mauth_base_url<-"https://mauth-sandbox.imedidata.net" 57 | mauth_api_version<-"v1" 58 | app_uuid<- "aaabbbcc-dddd-abcd-abcd-eff6b4b0b637" 59 | c<-RMauthClient(mauth_base_url, mauth_api_version, app_uuid, testKey) 60 | 61 | #it should return an error for http verbs not supported. 62 | checkException(makeMAuthCall(c, "PUT", "https://mdsol.com", "/api/v1/tests", "xyz")) 63 | 64 | #it should return an error when the config isn't available or null 65 | checkException(RMauthClient("blahblahblah")) 66 | 67 | #it should return an error when the configuration is missing items 68 | checkException(RMAuthClient(mauth_base_url="https://mauth-sandbox.imedidata.net", 69 | mauth_api_version="v1", 70 | private_key=testKey)) 71 | 72 | #it should return an error if the private key is not found 73 | c@private_key="" 74 | checkException(composeMAuthHeader(c, "GET", "https://mdsol.com", "/api/v1/tests", "")) 75 | 76 | 77 | } -------------------------------------------------------------------------------- /R/RMauthClient.R: -------------------------------------------------------------------------------- 1 | RMauthClient<-setClass( 2 | "RMauthClient", 3 | slots=c( 4 | app_uuid="character", 5 | mauth_base_url="character", 6 | mauth_api_version="character", 7 | private_key="character" 8 | ) 9 | ) 10 | 11 | setMethod("initialize", 12 | "RMauthClient", 13 | function(.Object, 14 | app_uuid=NULL, 15 | mauth_base_url=NULL, 16 | mauth_api_version="v1", 17 | private_key=NULL 18 | ) 19 | { 20 | requiredConfigs<- c("app_uuid", "mauth_base_url", "mauth_api_version", "private_key") 21 | 22 | lapply(seq(1,length(requiredConfigs)), function(c){ 23 | if(is.null(eval(as.symbol(requiredConfigs[c])))){ 24 | stop(paste("missing config element", requiredConfigs[c])) 25 | } 26 | }) 27 | 28 | .Object@app_uuid <- app_uuid 29 | .Object@mauth_base_url <- mauth_base_url 30 | .Object@mauth_api_version <- mauth_api_version 31 | .Object@private_key <- private_key 32 | .Object 33 | }) 34 | 35 | composeMAuthHeader<-function(RMauthClientObject, method, base_url, route, body="") 36 | { 37 | load_pk<-function() 38 | { 39 | PKI.load.key(what=RMauthClientObject@private_key, format = "PEM", private = T) 40 | } 41 | 42 | make_headers<-function(app_uuid, signature, time) 43 | { 44 | list( 45 | 'X-MWS-Authentication' = sprintf('MWS %s:%s',app_uuid,signature), 46 | 'X-MWS-Time' = time, 47 | 'Content-Type' = 'application/json;charset=utf-8') 48 | } 49 | 50 | make_request_string<-function(app_uuid, route, http_req_method, message_body, time) 51 | { 52 | s<-sprintf('%s\n%s\n%s\n%s\n%s', http_req_method, route, message_body, app_uuid, time) 53 | sha512(s) 54 | } 55 | 56 | generate_padding<-function(hashed_bin, keylength) 57 | { 58 | padding_length=keylength-length(hashed_bin)-3 59 | as.raw(c(0x00,0x01, rep(0xff, padding_length),0x00,hashed_bin)) 60 | } 61 | 62 | sign_request<-function(request_string, pk) 63 | { 64 | PKI.pencrypt(generate_padding(charToRaw(request_string),256), key=pk) 65 | } 66 | 67 | request_time<-as.character(as.integer(Sys.time())) 68 | 69 | private_key<-load_pk() 70 | signed_string<-sign_request(make_request_string(RMauthClientObject@app_uuid, route, method, body, request_time), 71 | private_key) 72 | 73 | make_headers(RMauthClientObject@app_uuid, base64_encode(signed_string), request_time) 74 | } 75 | 76 | makeMAuthCall<-function(RMauthClientObject, method, base_url, route, queryString="", retryAttempts=5, body="",pause_cap=1800, header_overrides=NULL) 77 | { 78 | 79 | 80 | fullRoute=paste0(route, queryString) 81 | 82 | mAuthHeader<-composeMAuthHeader(RMauthClientObject, method, base_url, route, body) 83 | 84 | if(!is.null(header_overrides) && !is.null(header_overrides$`Content-Type`)){ 85 | mAuthHeader$`Content-Type`<-NULL 86 | mAuthHeader<-append(mAuthHeader, header_overrides) 87 | } else if (!is.null(header_overrides)){ 88 | mAuthHeader<-append(mAuthHeader, header_overrides) 89 | } 90 | 91 | mAuthHeader<-setNames(as.character(mAuthHeader), names(mAuthHeader)) 92 | requestURL = paste0(base_url,fullRoute) 93 | 94 | if(method=="GET") 95 | { 96 | RETRY(verb = "GET", url = requestURL, config = add_headers(.headers = mAuthHeader), times = retryAttempts) 97 | } else if (method=="POST"){ 98 | RETRY(verb = "POST", url = requestURL, config = add_headers(.headers = mAuthHeader), body=body, pause_cap=pause_cap, times = retryAttempts) 99 | } else if (method=="PUT"){ 100 | RETRY(verb = "PUT", url = requestURL, config = add_headers(.headers = mAuthHeader), body=body, pause_cap=pause_cap, times = retryAttempts) 101 | } else if (method=="DELETE"){ 102 | RETRY(verb = "DELETE", url = requestURL, config = add_headers(.headers = mAuthHeader), times = retryAttempts) 103 | } else { 104 | stop("Unsupported HTTP Verb. Please use only GET, POST, PUT or DELETE.") 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RMauthClient 2 | 3 | This simple library can enable you to post and get requests via MAuth v1 in R. It should return back to you a valid response after authorization, which you will have to interpret on your own. 4 | 5 | 6 | ## Usage 7 | 8 | First of all, you will need a special version of the PKI library for R which has SHA512 support, and support for private_encrypt (deprecated in openssl, replaced by sign(), though slightly different from what MAuth v1 needs). 9 | 10 | Before you install this though, make sure you have the libraries `base64enc` and `openssl` pre-installed via the `install.packages` command. 11 | 12 | Using the base PKI library, I added code to support SHA512 and included this version of PKI in a fork [mdsol/PKI](https://github.com/mdsol/PKI). 13 | 14 | You should first install the above libraries `base64enc` and `openssl`, as well as installing `mdsol/PKI` via `devtools::install_github` before proceeding. 15 | 16 | To install this library, you can also do so by executing `devtools::install_github`. 17 | 18 | You can also use RStudio to build a package by going to `Build>Build Source Package`, which you will then use to install (ie. `R CMD install ....`) 19 | 20 | Note, that depending on your version of the compiler and OS, you may receive an error when trying to install the library. But, nevertheless, the library should install properly. 21 | 22 | 23 | ## Making Requests 24 | 25 | First, you need a set of keys, public and private, for which has been previously authorized with a target Mauth instance. 26 | 27 | Registering and generating a key is beyond the scope of this readme, but you should be able to do it with the following commands on your Unix/ Linux terminal (it is a 2048 bit key): 28 | 29 | ``` 30 | openssl genrsa -out yourname_mauth.priv.key 2048 31 | chmod 0600 yourname_mauth.priv.key 32 | openssl rsa -in yourname_mauth.priv.key -pubout -out yourname_mauth.pub.key 33 | ``` 34 | 35 | Once you have your key, registered with a valid MAuth instance, you should be able to make calls with this library to your designated resource(s). 36 | 37 | The following example demonstrates how to use the library to perform valid MAuth requests: 38 | 39 | 1) Your private key will be passed in as a vector, which each line representing a line in the pem file. From a contiguous string with `\n` delimiting lines, you can transform your key in R by doing the following: 40 | 41 | ``` 42 | key<-as.vector(strsplit("-----BEGIN RSA PRIVATE KEY-----\n...your key here\n-----END RSA PRIVATE KEY-----", '\n'))[[1]] 43 | ``` 44 | 45 | 2) Using the key, create an instance of the RMauthClient class: 46 | 47 | ``` 48 | myMauthClient<- RMauthClient(app_uuid="12345678-4599-47db-b57d-b6e750596500", 49 | mauth_base_url="https://mauth-sandbox.imedidata.net", 50 | private_key=key) 51 | ``` 52 | 53 | 3) Now that you have an instance of the RMauthClient class, you may use it to make valid calls to your resource: 54 | 55 | ``` 56 | response<-makeMAuthCall(myMauthClient, "GET", "https://eureka-sandbox.imedidata.net", "/v1/apis", "") 57 | ``` 58 | 59 | 4) I use httr to perform the GET and POST requests to the resources, therefore, you can get your reponse blob out either using: 60 | 61 | ``` 62 | content(response, "text") 63 | ``` 64 | 65 | Or, if your resource is outputting JSON, then you may use the following: 66 | 67 | ``` 68 | content(response) 69 | ``` 70 | 71 | However, that might be messy as the way the httr gives back JSON responses is not very good for data analysis purposes, so you might want to use `RJSONIO` or other packages specialized in reading and transforming your specific content types. 72 | 73 | For a complete example including all this, please see the examples/exampleUse.R 74 | 75 | 76 | ## Unit Tests 77 | 78 | There are some unit tests done using RUnit. Since this is outside the package, you should install the RUnit package on your own by doing `install.packages("RUnit")`. 79 | 80 | To run the tests, simply use RStudio to load up the RMauthClient.Rproj and then navigate to the `tests` directory. Source `run_tests.R`. 81 | 82 | To add tests, simply add more R files to the tests folder by naming them appropriately (ie. 1.R, 2.R, etc.). Inside each file, create a function that describes your test suite, and inside that put your tests for that feature. Please see 1.R for an example. 83 | 84 | 85 | ## Package Usage 86 | 87 | Please see the Documentation for the package inside R once loaded up. 88 | 89 | 90 | ## Contributing 91 | 92 | Sure, why not? Please send a PR as necessary for review. 93 | --------------------------------------------------------------------------------