http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/DynRoleMembership.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/DynRoleMembership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/DynRoleMembership.java new file mode 100644 index 0000000..5b253d8 --- /dev/null +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/DynRoleMembership.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.DynMembership; +import org.apache.syncope.core.persistence.api.entity.Role; + +public interface DynRoleMembership extends DynMembership<User> { + + Role getRole(); + + void setRole(Role role); +}
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerAttr.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerAttr.java index 9c88907..b3ebdec 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerAttr.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerAttr.java @@ -20,12 +20,6 @@ package org.apache.syncope.core.persistence.api.entity.user; import org.apache.syncope.core.persistence.api.entity.DerAttr; -public interface UDerAttr extends DerAttr { - - @Override - User getOwner(); - - @Override - UDerSchema getSchema(); +public interface UDerAttr extends DerAttr<User> { } http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerSchema.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerSchema.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerSchema.java deleted file mode 100644 index f9c75f0..0000000 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDerSchema.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.api.entity.user; - -import org.apache.syncope.core.persistence.api.entity.DerSchema; - -public interface UDerSchema extends DerSchema { - -} http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynGroupMembership.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynGroupMembership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynGroupMembership.java new file mode 100644 index 0000000..efec3f1 --- /dev/null +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynGroupMembership.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.DynGroupMembership; + +public interface UDynGroupMembership extends DynGroupMembership<User> { + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynMembership.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynMembership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynMembership.java new file mode 100644 index 0000000..7901a6e --- /dev/null +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UDynMembership.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.DynMembership; + +public interface UDynMembership extends DynMembership<User> { + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMapping.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMapping.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMapping.java deleted file mode 100644 index f99b4bc..0000000 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMapping.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.api.entity.user; - -import org.apache.syncope.core.persistence.api.entity.Mapping; - -public interface UMapping extends Mapping<UMappingItem> { - - UMappingItem getPasswordItem(); - - boolean setPasswordItem(UMappingItem item); -} http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMappingItem.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMappingItem.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMappingItem.java deleted file mode 100644 index a21aa0a..0000000 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMappingItem.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.api.entity.user; - -import org.apache.syncope.core.persistence.api.entity.Mapping; -import org.apache.syncope.core.persistence.api.entity.MappingItem; - -public interface UMappingItem extends MappingItem { - - @Override - Mapping<UMappingItem> getMapping(); - -} http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMembership.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMembership.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMembership.java new file mode 100644 index 0000000..76f9ef6 --- /dev/null +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UMembership.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.Membership; + +public interface UMembership extends Membership<User> { + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttr.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttr.java index fa861d9..5c91acf 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttr.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttr.java @@ -21,13 +21,7 @@ package org.apache.syncope.core.persistence.api.entity.user; import java.util.List; import org.apache.syncope.core.persistence.api.entity.PlainAttr; -public interface UPlainAttr extends PlainAttr { - - @Override - User getOwner(); - - @Override - UPlainSchema getSchema(); +public interface UPlainAttr extends PlainAttr<User> { @Override List<? extends UPlainAttrValue> getValues(); http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrUniqueValue.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrUniqueValue.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrUniqueValue.java index db3ff47..71eb24e 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrUniqueValue.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainAttrUniqueValue.java @@ -25,7 +25,4 @@ public interface UPlainAttrUniqueValue extends PlainAttrUniqueValue { @Override UPlainAttr getAttr(); - @Override - UPlainSchema getSchema(); - } http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainSchema.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainSchema.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainSchema.java deleted file mode 100644 index b9126af..0000000 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UPlainSchema.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.api.entity.user; - -import org.apache.syncope.core.persistence.api.entity.PlainSchema; - -public interface UPlainSchema extends PlainSchema { - -} http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/URelationship.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/URelationship.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/URelationship.java new file mode 100644 index 0000000..2a4c97b --- /dev/null +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/URelationship.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.api.entity.user; + +import org.apache.syncope.core.persistence.api.entity.Relationship; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; + +public interface URelationship extends Relationship<User, AnyObject> { + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirAttr.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirAttr.java index 12f1b5e..bb3ab70 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirAttr.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirAttr.java @@ -20,12 +20,6 @@ package org.apache.syncope.core.persistence.api.entity.user; import org.apache.syncope.core.persistence.api.entity.VirAttr; -public interface UVirAttr extends VirAttr { - - @Override - User getOwner(); - - @Override - UVirSchema getSchema(); +public interface UVirAttr extends VirAttr<User> { } http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirSchema.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirSchema.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirSchema.java deleted file mode 100644 index 3768d6f..0000000 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/UVirSchema.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.api.entity.user; - -import org.apache.syncope.core.persistence.api.entity.VirSchema; - -public interface UVirSchema extends VirSchema { - -} http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java index 7349ecb..d896984 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java @@ -18,129 +18,104 @@ */ package org.apache.syncope.core.persistence.api.entity.user; -import java.util.Collection; import java.util.Date; import java.util.List; import org.apache.syncope.common.lib.types.CipherAlgorithm; +import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.Role; -import org.apache.syncope.core.persistence.api.entity.Subject; -import org.apache.syncope.core.persistence.api.entity.membership.Membership; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; -public interface User extends Subject<UPlainAttr, UDerAttr, UVirAttr> { +public interface User extends Any<UPlainAttr, UDerAttr, UVirAttr> { - boolean addRole(Role role); + String getUsername(); - boolean addMembership(Membership membership); + void setUsername(String username); - boolean canDecodePassword(); + String getToken(); - boolean checkToken(String token); + Date getTokenExpireTime(); void generateToken(int tokenLength, int tokenExpireTime); - Date getChangePwdDate(); - - CipherAlgorithm getCipherAlgorithm(); - - String getClearPassword(); - - Integer getFailedLogins(); - - Date getLastLoginDate(); - - List<? extends Role> getRoles(); - - Membership getMembership(Long groupKey); - - List<? extends Membership> getMemberships(); - - Collection<Long> getStaticGroupKeys(); - - String getPassword(); - - List<String> getPasswordHistory(); - - String getSecurityAnswer(); + void removeToken(); - SecurityQuestion getSecurityQuestion(); + boolean checkToken(String token); - String getStatus(); + boolean hasTokenExpired(); - String getToken(); + Date getChangePwdDate(); - Date getTokenExpireTime(); + void setChangePwdDate(Date changePwdDate); - String getUsername(); + CipherAlgorithm getCipherAlgorithm(); - String getWorkflowId(); + void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm); - boolean hasTokenExpired(); + boolean canDecodePassword(); - Boolean isSuspended(); + String getClearPassword(); void removeClearPassword(); - boolean removeRole(Role role); - - boolean removeMembership(Membership membership); + String getPassword(); - void removeToken(); + void setEncodedPassword(String password, CipherAlgorithm cipherAlgoritm); - void setChangePwdDate(Date changePwdDate); + void setPassword(String password, CipherAlgorithm cipherAlgoritm); - void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm); + List<String> getPasswordHistory(); - void setEncodedPassword(String password, CipherAlgorithm cipherAlgoritm); + boolean verifyPasswordHistory(String password, int size); - void setFailedLogins(Integer failedLogins); + SecurityQuestion getSecurityQuestion(); - void setLastLoginDate(Date lastLoginDate); + void setSecurityQuestion(SecurityQuestion securityQuestion); - void setPassword(String password, CipherAlgorithm cipherAlgoritm); + String getSecurityAnswer(); void setSecurityAnswer(String securityAnswer); - void setSecurityQuestion(SecurityQuestion securityQuestion); + Integer getFailedLogins(); - void setStatus(String status); + void setFailedLogins(Integer failedLogins); - void setSuspended(Boolean suspended); + Date getLastLoginDate(); - void setUsername(String username); + void setLastLoginDate(Date lastLoginDate); - void setWorkflowId(String workflowId); + Boolean isSuspended(); - boolean verifyPasswordHistory(String password, int size); + void setSuspended(Boolean suspended); @Override - boolean addPlainAttr(UPlainAttr attr); + boolean add(UPlainAttr attr); @Override - boolean removePlainAttr(UPlainAttr attr); + boolean remove(UPlainAttr attr); @Override - boolean addDerAttr(UDerAttr attr); + UPlainAttr getPlainAttr(String plainSchemaName); @Override - boolean removeDerAttr(UDerAttr derAttr); + List<? extends UPlainAttr> getPlainAttrs(); @Override - boolean addVirAttr(UVirAttr attr); + boolean add(UDerAttr attr); @Override - boolean removeVirAttr(UVirAttr virAttr); + boolean remove(UDerAttr derAttr); @Override - UPlainAttr getPlainAttr(String plainSchemaName); + UDerAttr getDerAttr(String derSchemaName); @Override - List<? extends UPlainAttr> getPlainAttrs(); + List<? extends UDerAttr> getDerAttrs(); @Override - UDerAttr getDerAttr(String derSchemaName); + boolean add(UVirAttr attr); @Override - List<? extends UDerAttr> getDerAttrs(); + boolean remove(UVirAttr virAttr); @Override UVirAttr getVirAttr(String virSchemaName); @@ -148,4 +123,25 @@ public interface User extends Subject<UPlainAttr, UDerAttr, UVirAttr> { @Override List<? extends UVirAttr> getVirAttrs(); + boolean add(Role role); + + boolean remove(Role role); + + List<? extends Role> getRoles(); + + boolean add(URelationship relationship); + + boolean remove(URelationship relationship); + + URelationship getRelationship(AnyObject rightEnd); + + List<? extends URelationship> getRelationships(); + + boolean add(UMembership membership); + + boolean remove(UMembership membership); + + UMembership getMembership(Long groupKey); + + List<? extends UMembership> getMemberships(); } http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java index bc5f6e3..ea13072 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java @@ -52,17 +52,21 @@ import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.core.misc.DataFormat; import org.apache.syncope.core.persistence.api.content.ContentExporter; import org.apache.syncope.core.persistence.jpa.entity.JPAReportExec; -import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerAttr; -import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirAttr; -import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADerAttr; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttr; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrValue; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAVirAttr; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject; import org.apache.syncope.core.persistence.jpa.entity.task.JPATaskExec; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerAttr; +import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttr; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue; +import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirAttr; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser; import org.springframework.jdbc.datasource.DataSourceUtils; @@ -82,8 +86,9 @@ public class XMLContentExporter extends AbstractContentDealer implements Content "QRTZ_", "LOGGING", JPAReportExec.TABLE, JPATaskExec.TABLE, JPAUser.TABLE, JPAUPlainAttr.TABLE, JPAUPlainAttrValue.TABLE, JPAUPlainAttrUniqueValue.TABLE, JPAUDerAttr.TABLE, JPAUVirAttr.TABLE, - JPAMembership.TABLE, JPAMPlainAttr.TABLE, JPAMPlainAttrValue.TABLE, JPAMPlainAttrUniqueValue.TABLE, - JPAMDerAttr.TABLE, JPAMVirAttr.TABLE + JPAAnyObject.TABLE, JPAAPlainAttr.TABLE, JPAAPlainAttrValue.TABLE, JPAAPlainAttrUniqueValue.TABLE, + JPAADerAttr.TABLE, JPAAVirAttr.TABLE, + JPAARelationship.TABLE, JPAAMembership.TABLE, JPAURelationship.TABLE, JPAUMembership.TABLE })); protected static final Set<String> TABLE_SUFFIXES_TO_BE_INCLUDED = http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java new file mode 100644 index 0000000..3448737 --- /dev/null +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java @@ -0,0 +1,434 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.jpa.dao; + +import static org.apache.syncope.core.persistence.jpa.dao.AbstractDAO.LOG; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; +import javax.persistence.NoResultException; +import javax.persistence.Query; +import javax.persistence.TemporalType; +import org.apache.commons.jexl2.parser.Parser; +import org.apache.commons.jexl2.parser.ParserConstants; +import org.apache.commons.jexl2.parser.Token; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.core.persistence.api.dao.AnyDAO; +import org.apache.syncope.core.persistence.api.dao.AnySearchDAO; +import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; +import org.apache.syncope.core.persistence.api.dao.search.AnyCond; +import org.apache.syncope.core.persistence.api.dao.search.AttributeCond; +import org.apache.syncope.core.persistence.api.dao.search.OrderByClause; +import org.apache.syncope.core.persistence.api.dao.search.SearchCond; +import org.apache.syncope.core.persistence.api.entity.Any; +import org.apache.syncope.core.persistence.api.entity.AnyUtils; +import org.apache.syncope.core.persistence.api.entity.DerSchema; +import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; +import org.apache.syncope.core.persistence.api.entity.VirAttr; +import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; +import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; +import org.springframework.beans.factory.annotation.Autowired; + +public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO<A, Long> implements AnyDAO<A> { + + @Autowired + protected PlainSchemaDAO plainSchemaDAO; + + @Autowired + protected DerSchemaDAO derSchemaDAO; + + @Autowired + protected AnySearchDAO searchDAO; + + protected AnyUtils anyUtils; + + protected abstract AnyUtils init(); + + protected AnyUtils getAnyUtils() { + synchronized (this) { + if (anyUtils == null) { + anyUtils = init(); + } + } + return anyUtils; + } + + protected abstract void securityChecks(A any); + + @Override + public A authFind(final Long key) { + if (key == null) { + throw new NotFoundException("Null key"); + } + + A any = find(key); + if (any == null) { + throw new NotFoundException("Any " + key); + } + + securityChecks(any); + + return any; + } + + @Override + @SuppressWarnings("unchecked") + public A find(final Long key) { + return (A) entityManager.find(getAnyUtils().anyClass(), key); + } + + @SuppressWarnings("unchecked") + @Override + public A findByWorkflowId(final String workflowId) { + Query query = entityManager.createQuery("SELECT e FROM " + getAnyUtils().anyClass().getSimpleName() + + " e WHERE e.workflowId = :workflowId", User.class); + query.setParameter("workflowId", workflowId); + + A result = null; + try { + result = (A) query.getSingleResult(); + } catch (NoResultException e) { + LOG.debug("No user found with workflow id {}", workflowId, e); + } + + return result; + } + + private Query findByAttrValueQuery(final String entityName) { + return entityManager.createQuery("SELECT e FROM " + entityName + " e" + + " WHERE e.attribute.schema.name = :schemaName AND (e.stringValue IS NOT NULL" + + " AND e.stringValue = :stringValue)" + + " OR (e.booleanValue IS NOT NULL AND e.booleanValue = :booleanValue)" + + " OR (e.dateValue IS NOT NULL AND e.dateValue = :dateValue)" + + " OR (e.longValue IS NOT NULL AND e.longValue = :longValue)" + + " OR (e.doubleValue IS NOT NULL AND e.doubleValue = :doubleValue)"); + } + + @Override + @SuppressWarnings("unchecked") + public List<A> findByAttrValue(final String schemaName, final PlainAttrValue attrValue) { + PlainSchema schema = plainSchemaDAO.find(schemaName); + if (schema == null) { + LOG.error("Invalid schema name '{}'", schemaName); + return Collections.<A>emptyList(); + } + + String entityName = schema.isUniqueConstraint() + ? getAnyUtils().plainAttrUniqueValueClass().getName() + : getAnyUtils().plainAttrValueClass().getName(); + Query query = findByAttrValueQuery(entityName); + query.setParameter("schemaName", schemaName); + query.setParameter("stringValue", attrValue.getStringValue()); + query.setParameter("booleanValue", attrValue.getBooleanValue() == null + ? null + : ((AbstractPlainAttrValue) attrValue).getBooleanAsInteger(attrValue.getBooleanValue())); + if (attrValue.getDateValue() == null) { + query.setParameter("dateValue", null); + } else { + query.setParameter("dateValue", attrValue.getDateValue(), TemporalType.TIMESTAMP); + } + query.setParameter("longValue", attrValue.getLongValue()); + query.setParameter("doubleValue", attrValue.getDoubleValue()); + + List<A> result = new ArrayList<>(); + for (PlainAttrValue value : (List<PlainAttrValue>) query.getResultList()) { + A any = (A) value.getAttr().getOwner(); + if (!result.contains(any)) { + result.add(any); + } + } + + return result; + } + + @Override + public A findByAttrUniqueValue(final String schemaName, final PlainAttrValue attrUniqueValue) { + PlainSchema schema = plainSchemaDAO.find(schemaName); + if (schema == null) { + LOG.error("Invalid schema name '{}'", schemaName); + return null; + } + if (!schema.isUniqueConstraint()) { + LOG.error("This schema has not unique constraint: '{}'", schemaName); + return null; + } + + List<A> result = findByAttrValue(schemaName, attrUniqueValue); + return result.isEmpty() + ? null + : result.iterator().next(); + } + + /** + * Split an attribute value recurring on provided literals/tokens. + * + * @param attrValue value to be split + * @param literals literals/tokens + * @return split value + */ + private List<String> split(final String attrValue, final List<String> literals) { + final List<String> attrValues = new ArrayList<>(); + + if (literals.isEmpty()) { + attrValues.add(attrValue); + } else { + for (String token : attrValue.split(Pattern.quote(literals.get(0)))) { + attrValues.addAll(split(token, literals.subList(1, literals.size()))); + } + } + + return attrValues; + } + + /** + * Generate one where clause for each different attribute schema into the derived schema expression provided. + * + * @param expression derived schema expression + * @param value derived attribute value + * @param attrUtils USER / GROUP + * @return where clauses to use to build the query + */ + private Set<String> getWhereClause(final String expression, final String value) { + final Parser parser = new Parser(new StringReader(expression)); + + // Schema names + final List<String> identifiers = new ArrayList<>(); + + // Literals + final List<String> literals = new ArrayList<>(); + + // Get schema names and literals + for (Token token = parser.getNextToken(); token != null && StringUtils.isNotBlank(token.toString()); + token = parser.getNextToken()) { + + if (token.kind == ParserConstants.STRING_LITERAL) { + literals.add(token.toString().substring(1, token.toString().length() - 1)); + } + + if (token.kind == ParserConstants.IDENTIFIER) { + identifiers.add(token.toString()); + } + } + + // Sort literals in order to process later literals included into others + Collections.sort(literals, new Comparator<String>() { + + @Override + public int compare(final String t, final String t1) { + if (t == null && t1 == null) { + return 0; + } else if (t != null && t1 == null) { + return -1; + } else if (t == null && t1 != null) { + return 1; + } else if (t.length() == t1.length()) { + return 0; + } else if (t.length() > t1.length()) { + return -1; + } else { + return 1; + } + } + }); + + // Split value on provided literals + final List<String> attrValues = split(value, literals); + + if (attrValues.size() != identifiers.size()) { + LOG.error("Ambiguous JEXL expression resolution."); + throw new IllegalArgumentException("literals and values have different size"); + } + + // clauses to be used with INTERSECTed queries + final Set<String> clauses = new HashSet<>(); + + // builder to build the clauses + final StringBuilder bld = new StringBuilder(); + + // Contains used identifiers in order to avoid replications + final Set<String> used = new HashSet<>(); + + // Create several clauses: one for eanch identifiers + for (int i = 0; i < identifiers.size(); i++) { + if (!used.contains(identifiers.get(i))) { + + // verify schema existence and get schema type + PlainSchema schema = plainSchemaDAO.find(identifiers.get(i)); + if (schema == null) { + LOG.error("Invalid schema name '{}'", identifiers.get(i)); + throw new IllegalArgumentException("Invalid schema name " + identifiers.get(i)); + } + + // clear builder + bld.delete(0, bld.length()); + + bld.append("("); + + // set schema name + bld.append("s.name = '").append(identifiers.get(i)).append("'"); + + bld.append(" AND "); + + bld.append("s.name = a.schema_name").append(" AND "); + + bld.append("a.id = v.attribute_id"); + + bld.append(" AND "); + + // use a value clause different for eanch different schema type + switch (schema.getType()) { + case Boolean: + bld.append("v.booleanValue = '").append(attrValues.get(i)).append("'"); + break; + case Long: + bld.append("v.longValue = ").append(attrValues.get(i)); + break; + case Double: + bld.append("v.doubleValue = ").append(attrValues.get(i)); + break; + case Date: + bld.append("v.dateValue = '").append(attrValues.get(i)).append("'"); + break; + default: + bld.append("v.stringValue = '").append(attrValues.get(i)).append("'"); + } + + bld.append(")"); + + used.add(identifiers.get(i)); + + clauses.add(bld.toString()); + } + } + + LOG.debug("Generated where clauses {}", clauses); + + return clauses; + } + + @Override + public List<A> findByDerAttrValue(final String schemaName, final String value) { + DerSchema schema = derSchemaDAO.find(schemaName); + if (schema == null) { + LOG.error("Invalid schema name '{}'", schemaName); + return Collections.<A>emptyList(); + } + + // query string + StringBuilder querystring = new StringBuilder(); + + boolean subquery = false; + for (String clause : getWhereClause(schema.getExpression(), value)) { + if (querystring.length() > 0) { + subquery = true; + querystring.append(" AND a.owner_id IN ( "); + } + + querystring.append("SELECT a.owner_id "). + append("FROM ").append(getAnyUtils().plainAttrClass().getSimpleName().substring(3)).append(" a, "). + append(getAnyUtils().plainAttrValueClass().getSimpleName().substring(3)).append(" v, "). + append(PlainSchema.class.getSimpleName()).append(" s "). + append("WHERE ").append(clause); + + if (subquery) { + querystring.append(')'); + } + } + + Query query = entityManager.createNativeQuery(querystring.toString()); + + List<A> result = new ArrayList<>(); + for (Object anyKey : query.getResultList()) { + A any = find(Long.parseLong(anyKey.toString())); + if (!result.contains(any)) { + result.add(any); + } + } + + return result; + } + + @SuppressWarnings("unchecked") + @Override + public List<A> findByResource(final ExternalResource resource) { + Query query = entityManager.createQuery( + "SELECT e FROM " + getAnyUtils().anyClass().getSimpleName() + " e " + + "WHERE :resource MEMBER OF e.resources"); + query.setParameter("resource", resource); + + return query.getResultList(); + } + + @Override + public final List<A> findAll(final Set<String> adminRealms, + final int page, final int itemsPerPage) { + + return findAll(adminRealms, page, itemsPerPage, Collections.<OrderByClause>emptyList()); + } + + private SearchCond getAllMatchingCond() { + AnyCond idCond = new AnyCond(AttributeCond.Type.ISNOTNULL); + idCond.setSchema("id"); + return SearchCond.getLeafCond(idCond); + } + + @Override + public List<A> findAll(final Set<String> adminRealms, + final int page, final int itemsPerPage, final List<OrderByClause> orderBy) { + + return searchDAO.search(adminRealms, getAllMatchingCond(), page, itemsPerPage, orderBy, + getAnyUtils().getAnyTypeKind()); + } + + @Override + public final int count(final Set<String> adminRealms) { + return searchDAO.count(adminRealms, getAllMatchingCond(), getAnyUtils().getAnyTypeKind()); + } + + @Override + public A save(final A any) { + A merged = entityManager.merge(any); + for (VirAttr<?> virAttr : merged.getVirAttrs()) { + virAttr.getValues().clear(); + virAttr.getValues().addAll(any.getVirAttr(virAttr.getSchema().getKey()).getValues()); + } + + return merged; + } + + @Override + public void delete(final Long key) { + A any = find(key); + if (any == null) { + return; + } + + delete(any); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java index 2bf2b80..a4ff529 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java @@ -37,9 +37,6 @@ import org.springframework.util.ReflectionUtils; @Configurable public abstract class AbstractDAO<E extends Entity<KEY>, KEY> implements DAO<E, KEY> { - /** - * Logger. - */ protected static final Logger LOG = LoggerFactory.getLogger(DAO.class); private static final String CACHE_STORE_MODE = "javax.persistence.cache.storeMode"; http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java deleted file mode 100644 index 954651a..0000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao; - -import java.io.StringReader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.regex.Pattern; -import javax.persistence.Query; -import javax.persistence.TemporalType; -import org.apache.commons.jexl2.parser.Parser; -import org.apache.commons.jexl2.parser.ParserConstants; -import org.apache.commons.jexl2.parser.Token; -import org.apache.commons.lang3.StringUtils; -import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.SubjectDAO; -import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO; -import org.apache.syncope.core.persistence.api.dao.search.AttributeCond; -import org.apache.syncope.core.persistence.api.dao.search.SearchCond; -import org.apache.syncope.core.persistence.api.dao.search.SubjectCond; -import org.apache.syncope.core.persistence.api.entity.AttributableUtils; -import org.apache.syncope.core.persistence.api.entity.DerAttr; -import org.apache.syncope.core.persistence.api.entity.DerSchema; -import org.apache.syncope.core.persistence.api.entity.ExternalResource; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; -import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.Subject; -import org.apache.syncope.core.persistence.api.entity.VirAttr; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; -import org.springframework.beans.factory.annotation.Autowired; - -abstract class AbstractSubjectDAO<P extends PlainAttr, D extends DerAttr, V extends VirAttr> - extends AbstractDAO<Subject<P, D, V>, Long> implements SubjectDAO<P, D, V> { - - @Autowired - protected PlainSchemaDAO plainSchemaDAO; - - @Autowired - protected DerSchemaDAO derSchemaDAO; - - @Autowired - protected SubjectSearchDAO searchDAO; - - protected SearchCond getAllMatchingCond() { - SubjectCond idCond = new SubjectCond(AttributeCond.Type.ISNOTNULL); - idCond.setSchema("id"); - return SearchCond.getLeafCond(idCond); - } - - /** - * Split an attribute value recurring on provided literals/tokens. - * - * @param attrValue value to be split - * @param literals literals/tokens - * @return split value - */ - private List<String> split(final String attrValue, final List<String> literals) { - final List<String> attrValues = new ArrayList<>(); - - if (literals.isEmpty()) { - attrValues.add(attrValue); - } else { - for (String token : attrValue.split(Pattern.quote(literals.get(0)))) { - attrValues.addAll(split(token, literals.subList(1, literals.size()))); - } - } - - return attrValues; - } - - /** - * Generate one where clause for each different attribute schema into the derived schema expression provided. - * - * @param expression derived schema expression - * @param value derived attribute value - * @param attrUtils USER / GROUP - * @return where clauses to use to build the query - */ - private Set<String> getWhereClause(final String expression, final String value, final AttributableUtils attrUtils) { - final Parser parser = new Parser(new StringReader(expression)); - - // Schema names - final List<String> identifiers = new ArrayList<>(); - - // Literals - final List<String> literals = new ArrayList<>(); - - // Get schema names and literals - for (Token token = parser.getNextToken(); token != null && StringUtils.isNotBlank(token.toString()); - token = parser.getNextToken()) { - - if (token.kind == ParserConstants.STRING_LITERAL) { - literals.add(token.toString().substring(1, token.toString().length() - 1)); - } - - if (token.kind == ParserConstants.IDENTIFIER) { - identifiers.add(token.toString()); - } - } - - // Sort literals in order to process later literals included into others - Collections.sort(literals, new Comparator<String>() { - - @Override - public int compare(final String t, final String t1) { - if (t == null && t1 == null) { - return 0; - } else if (t != null && t1 == null) { - return -1; - } else if (t == null && t1 != null) { - return 1; - } else if (t.length() == t1.length()) { - return 0; - } else if (t.length() > t1.length()) { - return -1; - } else { - return 1; - } - } - }); - - // Split value on provided literals - final List<String> attrValues = split(value, literals); - - if (attrValues.size() != identifiers.size()) { - LOG.error("Ambiguous JEXL expression resolution."); - throw new IllegalArgumentException("literals and values have different size"); - } - - // clauses to be used with INTERSECTed queries - final Set<String> clauses = new HashSet<>(); - - // builder to build the clauses - final StringBuilder bld = new StringBuilder(); - - // Contains used identifiers in order to avoid replications - final Set<String> used = new HashSet<>(); - - // Create several clauses: one for eanch identifiers - for (int i = 0; i < identifiers.size(); i++) { - if (!used.contains(identifiers.get(i))) { - - // verify schema existence and get schema type - PlainSchema schema = plainSchemaDAO.find(identifiers.get(i), attrUtils.plainSchemaClass()); - if (schema == null) { - LOG.error("Invalid schema name '{}'", identifiers.get(i)); - throw new IllegalArgumentException("Invalid schema name " + identifiers.get(i)); - } - - // clear builder - bld.delete(0, bld.length()); - - bld.append("("); - - // set schema name - bld.append("s.name = '").append(identifiers.get(i)).append("'"); - - bld.append(" AND "); - - bld.append("s.name = a.schema_name").append(" AND "); - - bld.append("a.id = v.attribute_id"); - - bld.append(" AND "); - - // use a value clause different for eanch different schema type - switch (schema.getType()) { - case Boolean: - bld.append("v.booleanValue = '").append(attrValues.get(i)).append("'"); - break; - case Long: - bld.append("v.longValue = ").append(attrValues.get(i)); - break; - case Double: - bld.append("v.doubleValue = ").append(attrValues.get(i)); - break; - case Date: - bld.append("v.dateValue = '").append(attrValues.get(i)).append("'"); - break; - default: - bld.append("v.stringValue = '").append(attrValues.get(i)).append("'"); - } - - bld.append(")"); - - used.add(identifiers.get(i)); - - clauses.add(bld.toString()); - } - } - - LOG.debug("Generated where clauses {}", clauses); - - return clauses; - } - - protected abstract Subject<P, D, V> findInternal(Long key); - - private Query findByAttrValueQuery(final String entityName) { - return entityManager.createQuery("SELECT e FROM " + entityName + " e" - + " WHERE e.attribute.schema.name = :schemaName AND (e.stringValue IS NOT NULL" - + " AND e.stringValue = :stringValue)" - + " OR (e.booleanValue IS NOT NULL AND e.booleanValue = :booleanValue)" - + " OR (e.dateValue IS NOT NULL AND e.dateValue = :dateValue)" - + " OR (e.longValue IS NOT NULL AND e.longValue = :longValue)" - + " OR (e.doubleValue IS NOT NULL AND e.doubleValue = :doubleValue)"); - } - - @Override - @SuppressWarnings("unchecked") - public List<? extends Subject<P, D, V>> findByAttrValue( - final String schemaName, final PlainAttrValue attrValue, final AttributableUtils attrUtils) { - - PlainSchema schema = plainSchemaDAO.find(schemaName, attrUtils.plainSchemaClass()); - if (schema == null) { - LOG.error("Invalid schema name '{}'", schemaName); - return Collections.<Subject<P, D, V>>emptyList(); - } - - final String entityName = schema.isUniqueConstraint() - ? attrUtils.plainAttrUniqueValueClass().getName() - : attrUtils.plainAttrValueClass().getName(); - - Query query = findByAttrValueQuery(entityName); - - query.setParameter("schemaName", schemaName); - query.setParameter("stringValue", attrValue.getStringValue()); - query.setParameter("booleanValue", attrValue.getBooleanValue() == null - ? null - : ((AbstractPlainAttrValue) attrValue).getBooleanAsInteger(attrValue.getBooleanValue())); - if (attrValue.getDateValue() == null) { - query.setParameter("dateValue", null); - } else { - query.setParameter("dateValue", attrValue.getDateValue(), TemporalType.TIMESTAMP); - } - query.setParameter("longValue", attrValue.getLongValue()); - query.setParameter("doubleValue", attrValue.getDoubleValue()); - - List<Subject<P, D, V>> result = new ArrayList<>(); - for (PlainAttrValue value : (List<PlainAttrValue>) query.getResultList()) { - Subject<P, D, V> subject = (Subject<P, D, V>) value.getAttr().getOwner(); - if (!result.contains(subject)) { - result.add(subject); - } - } - - return result; - } - - @Override - public Subject<P, D, V> findByAttrUniqueValue( - final String schemaName, final PlainAttrValue attrUniqueValue, final AttributableUtils attrUtils) { - - PlainSchema schema = plainSchemaDAO.find(schemaName, attrUtils.plainSchemaClass()); - if (schema == null) { - LOG.error("Invalid schema name '{}'", schemaName); - return null; - } - if (!schema.isUniqueConstraint()) { - LOG.error("This schema has not unique constraint: '{}'", schemaName); - return null; - } - - List<? extends Subject<P, D, V>> result = findByAttrValue(schemaName, attrUniqueValue, attrUtils); - return result.isEmpty() - ? null - : result.iterator().next(); - } - - /** - * Find users / groups by derived attribute value. This method could fail if one or more string literals contained - * into the derived attribute value provided derive from identifier (schema name) replacement. When you are going to - * specify a derived attribute expression you must be quite sure that string literals used to build the expression - * cannot be found into the attribute values used to replace attribute schema names used as identifiers. - * - * @param schemaName derived schema name - * @param value derived attribute value - * @param attrUtils AttributableUtil - * @return list of users / groups - */ - @Override - public List<? extends Subject<P, D, V>> findByDerAttrValue( - final String schemaName, final String value, final AttributableUtils attrUtils) { - - DerSchema schema = derSchemaDAO.find(schemaName, attrUtils.derSchemaClass()); - if (schema == null) { - LOG.error("Invalid schema name '{}'", schemaName); - return Collections.<Subject<P, D, V>>emptyList(); - } - - // query string - final StringBuilder querystring = new StringBuilder(); - - boolean subquery = false; - for (String clause : getWhereClause(schema.getExpression(), value, attrUtils)) { - if (querystring.length() > 0) { - subquery = true; - querystring.append(" AND a.owner_id IN ( "); - } - - querystring.append("SELECT a.owner_id "). - append("FROM ").append(attrUtils.plainAttrClass().getSimpleName().substring(3)).append(" a, "). - append(attrUtils.plainAttrValueClass().getSimpleName().substring(3)).append(" v, "). - append(attrUtils.plainSchemaClass().getSimpleName().substring(3)).append(" s "). - append("WHERE ").append(clause); - - if (subquery) { - querystring.append(')'); - } - } - - LOG.debug("Execute query {}", querystring); - - final Query query = entityManager.createNativeQuery(querystring.toString()); - - final List<Subject<P, D, V>> result = new ArrayList<>(); - for (Object userId : query.getResultList()) { - Subject<P, D, V> subject = findInternal(Long.parseLong(userId.toString())); - if (!result.contains(subject)) { - result.add(subject); - } - } - - return result; - } - - @Override - @SuppressWarnings("unchecked") - public List<? extends Subject<P, D, V>> findByResource( - final ExternalResource resource, final AttributableUtils attrUtils) { - - Query query = entityManager.createQuery( - "SELECT e FROM " + attrUtils.attributableClass().getSimpleName() + " e " - + "WHERE :resource MEMBER OF e.resources"); - query.setParameter("resource", resource); - - return query.getResultList(); - } -} http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java new file mode 100644 index 0000000..fd99019 --- /dev/null +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java @@ -0,0 +1,149 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.jpa.dao; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import javax.persistence.TypedQuery; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.Predicate; +import org.apache.commons.collections4.Transformer; +import org.apache.syncope.common.lib.types.AnyTypeKind; +import org.apache.syncope.common.lib.types.Entitlement; +import org.apache.syncope.core.misc.security.AuthContextUtils; +import org.apache.syncope.core.misc.security.UnauthorizedException; +import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; +import org.apache.syncope.core.persistence.api.entity.AnyUtils; +import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; +import org.apache.syncope.core.persistence.api.entity.group.Group; +import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; +import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +@Repository +public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObjectDAO { + + @Override + protected AnyUtils init() { + return new JPAAnyUtilsFactory().getInstance(AnyTypeKind.ANY_OBJECT); + } + + @Override + protected void securityChecks(final AnyObject anyObject) { + Set<String> authRealms = AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_READ); + boolean authorized = CollectionUtils.exists(authRealms, new Predicate<String>() { + + @Override + public boolean evaluate(final String realm) { + return anyObject.getRealm().getFullPath().startsWith(realm); + } + }); + if (authRealms == null || authRealms.isEmpty() || !authorized) { + throw new UnauthorizedException(AnyTypeKind.ANY_OBJECT, anyObject.getKey()); + } + } + + @Override + public List<AnyObject> findByAnyType(final String anyTypeName) { + TypedQuery<AnyObject> query = entityManager.createQuery( + "SELECT e FROM " + JPAAnyObject.class.getSimpleName() + " e WHERE e.type.name=:name", AnyObject.class); + query.setParameter("name", anyTypeName); + + return query.getResultList(); + } + + @Override + public void delete(final AnyObject any) { + for (Group group : findDynGroupMemberships(any)) { + group.getADynMembership().remove(any); + } + + entityManager.remove(any); + } + + @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true) + @Override + public List<Group> findDynGroupMemberships(final AnyObject anyObject) { + TypedQuery<Group> query = entityManager.createQuery( + "SELECT e.group FROM " + JPAADynGroupMembership.class.getSimpleName() + + " e WHERE :anyObject MEMBER OF e.members", Group.class); + query.setParameter("anyObject", anyObject); + + return query.getResultList(); + } + + @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true) + @Override + public Collection<Group> findAllGroups(final AnyObject anyObject) { + return CollectionUtils.union( + CollectionUtils.collect(anyObject.getMemberships(), new Transformer<AMembership, Group>() { + + @Override + public Group transform(final AMembership input) { + return input.getRightEnd(); + } + }, new ArrayList<Group>()), + findDynGroupMemberships(anyObject)); + } + + @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true) + @Override + public Collection<Long> findAllGroupKeys(final AnyObject anyObject) { + return CollectionUtils.collect(findAllGroups(anyObject), new Transformer<Group, Long>() { + + @Override + public Long transform(final Group input) { + return input.getKey(); + } + }); + } + + @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true) + @Override + public Collection<ExternalResource> findAllResources(final AnyObject anyObject) { + Set<ExternalResource> result = new HashSet<>(); + result.addAll(anyObject.getResources()); + for (Group group : findAllGroups(anyObject)) { + result.addAll(group.getResources()); + } + + return result; + } + + @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true) + @Override + public Collection<String> findAllResourceNames(final AnyObject anyObject) { + return CollectionUtils.collect(findAllResources(anyObject), new Transformer<ExternalResource, String>() { + + @Override + public String transform(final ExternalResource input) { + return input.getKey(); + } + }); + } + +}
