Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
KaterynaHonchar committed Feb 22, 2019
2 parents b74a747 + f9f870b commit 92bea5d
Show file tree
Hide file tree
Showing 4 changed files with 305 additions and 0 deletions.
17 changes: 17 additions & 0 deletions samples/resources/scriptedsql/BaseScript.groovy
@@ -0,0 +1,17 @@
import org.identityconnectors.framework.common.objects.ObjectClass

class BaseScript extends Script {

public static final String GROUP_NAME = "Group"

public static final ObjectClass GROUP = new ObjectClass(BaseScript.GROUP_NAME)

public static final String ORGANIZATION_NAME = "Organization"

public static final ObjectClass ORGANIZATION = new ObjectClass(BaseScript.ORGANIZATION_NAME)

@Override
Object run() {
return null
}
}
80 changes: 80 additions & 0 deletions samples/resources/scriptedsql/CreateScript.groovy
@@ -0,0 +1,80 @@
import groovy.sql.Sql
import org.forgerock.openicf.connectors.scriptedsql.ScriptedSQLConfiguration
import org.forgerock.openicf.misc.scriptedcommon.OperationType
import org.identityconnectors.common.logging.Log
import org.identityconnectors.framework.common.exceptions.ConnectorException
import org.identityconnectors.framework.common.objects.Attribute
import org.identityconnectors.framework.common.objects.ObjectClass
import org.identityconnectors.framework.common.objects.OperationOptions
import org.identityconnectors.framework.common.objects.Uid
import org.identityconnectors.framework.common.objects.AttributeUtil

import java.sql.Connection

def log = log as Log
def operation = operation as OperationType
def options = options as OperationOptions
def objectClass = objectClass as ObjectClass
def attributes = attributes as Set<Attribute>
def connection = connection as Connection
def id = id as String
def configuration = configuration as ScriptedSQLConfiguration

log.info("Entering " + operation + " Script")

def sql = new Sql(connection)

switch (objectClass) {
case ObjectClass.ACCOUNT:
return handleAccount(sql)
case BaseScript.GROUP:
return handleGroup(sql)
case BaseScript.ORGANIZATION:
return handleOrganization(sql)
default:
throw new ConnectorException("Unknown object class " + objectClass)
}

Uid handleAccount(Sql sql) {
def keys = sql.executeInsert("INSERT INTO Users (login, firstname,lastname,fullname,email,organization,password,disabled) values (?,?,?,?,?,?,?,?)",
[
id,
AttributeUtil.getSingleValue("firstname"),
AttributeUtil.getSingleValue("lastname"),
AttributeUtil.getSingleValue("fullname"),
AttributeUtil.getSingleValue("email"),
AttributeUtil.getSingleValue("organization"),
// decrypt password
SecurityUtil.decrypt(AttributeUtil.getPasswordValue(attributes)),
// negate __ENABLE__ attribute
!(AttributeUtil.getSingleValue("__ENABLE__") as Boolean)

//attributes.get("firstname") ? attributes.get("firstname").get(0) : "",
//attributes.get("lastname") ? attributes.get("lastname").get(0) : "",
//attributes.get("fullname") ? attributes.get("fullname").get(0) : "",
//attributes.get("email") ? attributes.get("email").get(0) : "",
//attributes.get("organization") ? attributes.get("organization").get(0) : ""
])

return new Uid(keys[0][0])
}

Uid handleGroup(Sql sql) {
def keys = sql.executeInsert("INSERT INTO Groups (name,description) values (?,?)",
[
id,
AttributeUtil.getSingleValue("description")
])

return new Uid(keys[0][0])
}

Uid handleOrganization(Sql sql) {
def keys = sql.executeInsert("INSERT INTO Organizations (name,description) values (?,?)",
[
id,
AttributeUtil.getSingleValue("description")
])

return new Uid(keys[0][0])
}
50 changes: 50 additions & 0 deletions samples/resources/scriptedsql/SchemaScript.groovy
@@ -0,0 +1,50 @@
import org.forgerock.openicf.connectors.scriptedsql.ScriptedSQLConfiguration
import org.forgerock.openicf.misc.scriptedcommon.ICFObjectBuilder
import org.forgerock.openicf.misc.scriptedcommon.OperationType
import org.identityconnectors.common.logging.Log
import org.identityconnectors.framework.common.objects.ObjectClass
import org.identityconnectors.framework.common.objects.OperationOptionInfoBuilder
import org.identityconnectors.framework.spi.operations.SearchOp
import org.identityconnectors.framework.common.objects.OperationalAttributeInfos

import static org.identityconnectors.framework.common.objects.AttributeInfo.Flags.MULTIVALUED

def log = log as Log
def operation = operation as OperationType
def builder = builder as ICFObjectBuilder
def configuration = configuration as ScriptedSQLConfiguration

log.info("Entering " + operation + " Script")

builder.schema({
objectClass {
type ObjectClass.ACCOUNT_NAME
attributes {
firstname()
lastname()
fullname()
email()
organization()
OperationalAttributeInfos.ENABLE
OperationalAttributeInfos.PASSWORD
OperationalAttributeInfos.LOCK_OUT
}
}
objectClass {
type BaseScript.GROUP
attributes {
name String.class, MULTIVALUED
description()
}
}
objectClass {
type BaseScript.ORGANIZATION
attributes {
name()
description()
}
}

defineOperationOption OperationOptionInfoBuilder.buildPagedResultsOffset(), SearchOp
defineOperationOption OperationOptionInfoBuilder.buildPageSize(), SearchOp
})
158 changes: 158 additions & 0 deletions samples/resources/scriptedsql/SearchScript.groovy
@@ -0,0 +1,158 @@
import groovy.sql.Sql
import org.forgerock.openicf.connectors.scriptedsql.ScriptedSQLConfiguration
import org.forgerock.openicf.misc.scriptedcommon.ICFObjectBuilder
import org.forgerock.openicf.misc.scriptedcommon.MapFilterVisitor
import org.forgerock.openicf.misc.scriptedcommon.OperationType
import org.identityconnectors.common.logging.Log
import org.identityconnectors.framework.common.exceptions.ConnectorException
import org.identityconnectors.framework.common.objects.ObjectClass
import org.identityconnectors.framework.common.objects.OperationOptions
import org.identityconnectors.framework.common.objects.ResultsHandler
import org.identityconnectors.framework.common.objects.SearchResult
import org.identityconnectors.framework.common.objects.filter.Filter

import java.sql.Connection

def log = log as Log
def operation = operation as OperationType
def options = options as OperationOptions
def objectClass = objectClass as ObjectClass
def configuration = configuration as ScriptedSQLConfiguration
def filter = filter as Filter
def connection = connection as Connection
def query = query as Closure
def handler = handler as ResultsHandler

log.info("Entering " + operation + " Script")

def sql = new Sql(connection)

switch (objectClass) {
case ObjectClass.ACCOUNT:
handleAccount(sql)
break
case BaseScript.GROUP:
handleGroup(sql)
break
case BaseScript.ORGANIZATION:
handleOrganization(sql)
break
default:
throw new ConnectorException("Unknown object class " + objectClass)
}

return new SearchResult()

// =================================================================================

void handleAccount(Sql sql) {
Closure closure = { row ->
ICFObjectBuilder.co {
uid row.id as String
id row.login
attribute '__ENABLE__', !row.disabled
attribute 'fullname', row.fullname
attribute 'firstname', row.firstname
attribute 'lastname', row.lastname
attribute 'email', row.email
attribute 'organization', row.organization
}
}

Map params = [:]
String where = buildWhereClause(filter, params, 'id', 'login')

sql.eachRow(params, "SELECT * FROM Users " + where, closure);
}


void handleGroup(Sql sql) {
Closure closure = { row ->
ICFObjectBuilder.co {
uid row.id as String
id row.name
attribute 'description', row.description
}
}

Map params = [:]
String where = buildWhereClause(filter, params, 'id', 'name')

sql.eachRow(params, "SELECT * FROM Groups " + where, closure)
}

void handleOrganization(Sql sql) {
Closure closure = { row ->
ICFObjectBuilder.co {
uid row.id as String
id row.name
attribute 'description', row.description
}
}

Map params = [:]
String where = buildWhereClause(filter, params, 'id', 'name')

sql.eachRow(params, "SELECT * FROM Organizations " + where, closure)
}

static String buildWhereClause(Filter filter, Map sqlParams, String uidColumn, String nameColumn) {
if (filter == null) {
log.info("Returning empty where clause")
return ""
}

Map query = filter.accept(MapFilterVisitor.INSTANCE, null)

log.info("Building where clause, query {0}, uidcolumn {1}, nameColumn {2}", query, uidColumn, nameColumn)

String columnName = uidColumn.replaceFirst("[\\w]+\\.", "")

String left = query.get("left")
if (Uid.NAME.equals(left)) {
left = uidColumn
} else if (Name.NAME.equals(left)) {
left = nameColumn
}

String right = query.get("right")

String operation = query.get("operation")
switch (operation) {
case "CONTAINS":
right = '%' + right + '%'
break;
case "ENDSWITH":
right = '%' + right
break;
case "STARTSWITH":
right = right + '%'
break;
}

sqlParams.put(columnName, right)
right = ":" + columnName

def engine = new groovy.text.SimpleTemplateEngine()

def whereTemplates = [
CONTAINS : ' $left ${not ? "not " : ""}like $right',
ENDSWITH : ' $left ${not ? "not " : ""}like $right',
STARTSWITH : ' $left ${not ? "not " : ""}like $right',
EQUALS : ' $left ${not ? "<>" : "="} $right',
GREATERTHAN : ' $left ${not ? "<=" : ">"} $right',
GREATERTHANOREQUAL: ' $left ${not ? "<" : ">="} $right',
LESSTHAN : ' $left ${not ? ">=" : "<"} $right',
LESSTHANOREQUAL : ' $left ${not ? ">" : "<="} $right'
]

def wt = whereTemplates.get(operation)
def binding = [left: left, right: right, not: query.get("not")]
def template = engine.createTemplate(wt).make(binding)
def where = template.toString()

log.info("Where clause: {0}, with parameters {1}", where, sqlParams)

return where
}

0 comments on commit 92bea5d

Please sign in to comment.