diff --git a/DESCRIPTION b/DESCRIPTION index 55fb499..a3478bf 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -5,7 +5,7 @@ Authors@R: c( person("Hong", "Ooi", , "hongooi@microsoft.com", role = c("aut", "cre")), person("Microsoft", role="cph") ) -Description: A lightweight R interface to the 'Azure Active Directory Graph' REST API. +Description: A simple R interface to the 'Azure Active Directory Graph' REST API. URL: https://github.com/cloudyr/AzureGraph BugReports: https://github.com/cloudyr/AzureGraph/issues License: MIT + file LICENSE diff --git a/R/az_app.r b/R/az_app.r index 05c9db2..31228d1 100644 --- a/R/az_app.r +++ b/R/az_app.r @@ -33,17 +33,12 @@ public=list( # app data from server properties=NULL, - initialize=function(token, tenant=NULL, app_id=NULL, object_id=NULL, password=NULL, password_duration=1, ..., - deployed_properties=list()) + initialize=function(token, tenant=NULL, properties=NULL, password=NULL) { self$token <- token self$tenant <- tenant - - self$properties <- if(!is_empty(list(...))) - private$init_and_deploy(..., password=password, password_duration=password_duration) - else if(!is_empty(deployed_properties)) - private$init_from_parms(deployed_properties) - else private$init_from_host(app_id, object_id) + self$properties <- properties + private$password <- password }, delete=function(confirm=TRUE) @@ -56,84 +51,59 @@ public=list( return(invisible(NULL)) } - op <- file.path("applications", self$properties$objectId) - call_graph_endpoint(self$token, self$tenant, op, http_verb="DELETE") + op <- if(!is.null(self$properties$objectId)) + file.path("applications", self$properties$objectId) + else file.path("applicationsByAppId", self$properties$appId) + + private$graph_op(op, http_verb="DELETE") invisible(NULL) }, + update_password=function(...) + {}, + update=function(...) {}, sync_fields=function() { - self$properties <- private$init_from_host(app_id=NULL, object_id=self$properties$objectId) + op <- file.path("applications", self$properties$objectId) + self$properties <- call_graph_endpoint(self$token, self$tenant, op) invisible(self) }, create_service_principal=function(...) { - az_service_principal$new(self$token, self$tenant, app_id=self$properties$appId, ..., mode="create") + properties <- modifyList(list(...), list(appId=self$properties$appId)) + az_service_principal$new( + self$token, + self$tenant, + private$graph_op("servicePrincipals", body=properties, encode="json", http_verb="POST") + ) }, get_service_principal=function() { - az_service_principal$new(self$token, self$tenant, app_id=self$properties$appId, mode="get") + op <- file.path("servicePrincipalsByAppId", self$properties$appId) + az_service_principal$new( + self$token, + self$tenant, + private$graph_op(op) + ) }, delete_service_principal=function(confirm=TRUE) { - az_service_principal$new(self$token, self$tenant, app_id=self$properties$appId, - deployed_properties=list(NULL), mode="get")$ - delete(confirm=confirm) + self$get_service_principal()$delete(confirm=confirm) } ), private=list( - + password=NULL, - init_and_deploy=function(..., password, password_duration) + graph_op=function(op="", ...) { - properties <- list(...) - if(is.null(password) || password != FALSE) - { - key <- "awBlAHkAMQA=" # base64/UTF-16LE encoded "key1" - if(is.null(password)) - { - chars <- c(letters, LETTERS, 0:9, "~", "!", "@", "#", "$", "%", "&", "*", "(", ")", "-", "+") - password <- paste0(sample(chars, 50, replace=TRUE), collapse="") - } - - end_date <- if(is.finite(password_duration)) - { - now <- as.POSIXlt(Sys.time()) - now$year <- now$year + password_duration - format(as.POSIXct(now), "%Y-%m-%dT%H:%M:%SZ", tz="GMT") - } - else "2299-12-30T12:00:00Z" - - private$password <- password - properties <- modifyList(properties, list(passwordCredentials=list(list( - customKeyIdentifier=key, - endDate=end_date, - value=password - )))) - } - - call_graph_endpoint(self$token, self$tenant, "applications", body=properties, encode="json", http_verb="POST") - }, - - init_from_parms=function(parms) - { - parms - }, - - init_from_host=function(app_id, object_id) - { - op <- if(is.null(object_id)) - file.path("applicationsByAppId", app_id) - else file.path("applications", object_id) - - call_graph_endpoint(self$token, self$tenant, op) + call_graph_endpoint(self$token, self$tenant, op, ...) } )) diff --git a/R/az_graph.R b/R/az_graph.R index 7759fa1..4e016bb 100644 --- a/R/az_graph.R +++ b/R/az_graph.R @@ -112,8 +112,39 @@ public=list( create_app=function(name, ..., password=NULL, password_duration=1, create_service_principal=TRUE) { - res <- az_app$new(self$token, self$tenant, displayName=name, - password=password, password_duration=password_duration, ...) + properties <- list(...) + if(is.null(password) || password != FALSE) + { + key <- "awBlAHkAMQA=" # base64/UTF-16LE encoded "key1" + if(is.null(password)) + { + chars <- c(letters, LETTERS, 0:9, "~", "!", "@", "#", "$", "%", "&", "*", "(", ")", "-", "+") + password <- paste0(sample(chars, 50, replace=TRUE), collapse="") + } + + end_date <- if(is.finite(password_duration)) + { + now <- as.POSIXlt(Sys.time()) + now$year <- now$year + password_duration + format(as.POSIXct(now), "%Y-%m-%dT%H:%M:%SZ", tz="GMT") + } + else "2299-12-30T12:00:00Z" + + private$password <- password + properties <- modifyList(properties, list(passwordCredentials=list(list( + customKeyIdentifier=key, + endDate=end_date, + value=password + )))) + } + + res <- az_app$new( + self$token, + self$tenant, + private$graph_op("applications", body=properties, encode="json", http_verb="POST"), + password + ) + if(create_service_principal) res$create_service_principal() res @@ -121,7 +152,11 @@ public=list( get_app=function(app_id=NULL, object_id=NULL) { - az_app$new(self$token, self$tenant, app_id, object_id) + op <- if(is.null(object_id)) + file.path("applicationsByAppId", app_id) + else file.path("applications", object_id) + + az_app$new(self$token, self$tenant, private$graph_op(op)) }, delete_app=function(app_id=NULL, object_id=NULL, confirm=TRUE) @@ -131,12 +166,22 @@ public=list( create_service_principal=function(app_id, ...) { - az_service_principal$new(self$token, self$tenant, app_id=app_id, ..., mode="create") + self$get_app(app_id)$create_service_principal(...) }, get_service_principal=function(app_id=NULL, object_id=NULL) { - az_service_principal$new(self$token, self$tenant, app_id, object_id, mode="get") + if(!is.null(app_id)) + self$get_app(app_id=app_id)$get_service_principal() + else + { + op <- file.path("servicePrincipals", object_id) + az_service_principal$new( + self$token, + self$tenant, + private$graph_op(op) + ) + } }, delete_service_principal=function(app_id=NULL, object_id=NULL, confirm=TRUE) @@ -154,6 +199,14 @@ public=list( cat(format_public_methods(self)) invisible(self) } +), + +private=list( + + graph_op=function(op="", ...) + { + call_graph_endpoint(self$token, self$tenant, op, ...) + } )) diff --git a/R/az_svc_principal.R b/R/az_svc_principal.R index a044449..7d238dd 100644 --- a/R/az_svc_principal.R +++ b/R/az_svc_principal.R @@ -28,17 +28,11 @@ public=list( # app data from server properties=NULL, - # need explicit mode arg because initialize(app_id) can either create a new SP or get an existing one - initialize=function(token, tenant=NULL, app_id=NULL, object_id=NULL, ..., deployed_properties=list(), mode="get") + initialize=function(token, tenant=NULL, properties=NULL) { self$token <- token self$tenant <- tenant - - self$properties <- if(!is_empty(list(...)) || mode == "create") - private$init_and_deploy(appId=app_id, ...) - else if(!is_empty(deployed_properties)) - private$init_from_parms(deployed_properties) - else private$init_from_host(app_id, object_id) + self$properties <- properties }, delete=function(confirm=TRUE) @@ -52,32 +46,19 @@ public=list( return(invisible(NULL)) } - op <- file.path("servicePrincipals", self$properties$objectId) - call_graph_endpoint(self$token, self$tenant, op, http_verb="DELETE") + op <- if(!is_empty(self$properties$objectId)) + file.path("servicePrincipals", self$properties$objectId) + else file.path("servicePrincipalsByAppId", self$properties$appId) + + private$graph_op(op, http_verb="DELETE") invisible(NULL) } ), private=list( - init_and_deploy=function(...) + graph_op=function(op="", ...) { - properties <- list(...) - - call_graph_endpoint(self$token, self$tenant, "servicePrincipals", body=properties, encode="json", http_verb="POST") - }, - - init_from_parms=function(parms) - { - parms - }, - - init_from_host=function(app_id, object_id) - { - op <- if(is.null(object_id)) - file.path("servicePrincipalsByAppId", app_id) - else file.path("servicePrincipals", object_id) - - call_graph_endpoint(self$token, self$tenant, op) + call_graph_endpoint(self$token, self$tenant, op, ...) } ))