Creating next generation REST API
This commit is contained in:
parent
3c452c38f2
commit
023d88d7b0
|
@ -113,6 +113,9 @@ public class DefaultLdapRoleMapper
|
||||||
public static String DEFAULT_GROUP_NAME_ATTRIBUTE = "cn";
|
public static String DEFAULT_GROUP_NAME_ATTRIBUTE = "cn";
|
||||||
private String groupNameAttribute = DEFAULT_GROUP_NAME_ATTRIBUTE;
|
private String groupNameAttribute = DEFAULT_GROUP_NAME_ATTRIBUTE;
|
||||||
|
|
||||||
|
public static String DEFAULT_DESCRIPTION_ATTRIBUTE = "description";
|
||||||
|
private String descriptionAttribute = DEFAULT_DESCRIPTION_ATTRIBUTE;
|
||||||
|
|
||||||
// True, if the member attribute stores the DN, otherwise the userkey is used as entry value
|
// True, if the member attribute stores the DN, otherwise the userkey is used as entry value
|
||||||
private boolean useDnAsMemberValue = true;
|
private boolean useDnAsMemberValue = true;
|
||||||
|
|
||||||
|
@ -150,6 +153,8 @@ public class DefaultLdapRoleMapper
|
||||||
this.dnAttr = userConf.getString( UserConfigurationKeys.LDAP_DN_ATTRIBUTE, this.dnAttr );
|
this.dnAttr = userConf.getString( UserConfigurationKeys.LDAP_DN_ATTRIBUTE, this.dnAttr );
|
||||||
|
|
||||||
this.groupNameAttribute = userConf.getString( UserConfigurationKeys.LDAP_GROUP_NAME_ATTRIBUTE, DEFAULT_GROUP_NAME_ATTRIBUTE );
|
this.groupNameAttribute = userConf.getString( UserConfigurationKeys.LDAP_GROUP_NAME_ATTRIBUTE, DEFAULT_GROUP_NAME_ATTRIBUTE );
|
||||||
|
|
||||||
|
this.descriptionAttribute = userConf.getString( UserConfigurationKeys.LDAP_GROUP_DESCRIPTION_ATTRIBUTE, DEFAULT_DESCRIPTION_ATTRIBUTE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -222,6 +227,93 @@ public class DefaultLdapRoleMapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<LdapGroup> getAllGroupObjects( DirContext context ) throws MappingException
|
||||||
|
{
|
||||||
|
|
||||||
|
NamingEnumeration<SearchResult> namingEnumeration = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
SearchControls searchControls = new SearchControls( );
|
||||||
|
|
||||||
|
searchControls.setDerefLinkFlag( true );
|
||||||
|
searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
|
||||||
|
searchControls.setReturningAttributes( new String[]{ this.getLdapDnAttribute(), "objectClass", groupNameAttribute} );
|
||||||
|
|
||||||
|
String filter = "objectClass=" + getLdapGroupClass( );
|
||||||
|
|
||||||
|
if ( !StringUtils.isEmpty( this.groupFilter ) )
|
||||||
|
{
|
||||||
|
filter = "(&(" + filter + ")(" + this.groupFilter + "))";
|
||||||
|
}
|
||||||
|
|
||||||
|
namingEnumeration = context.search( getGroupsDn( ), filter, searchControls );
|
||||||
|
|
||||||
|
List<LdapGroup> allGroups = new ArrayList<>( );
|
||||||
|
|
||||||
|
while ( namingEnumeration.hasMore( ) )
|
||||||
|
{
|
||||||
|
SearchResult searchResult = namingEnumeration.next( );
|
||||||
|
allGroups.add( getGroupFromResult( searchResult ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return allGroups;
|
||||||
|
}
|
||||||
|
catch ( LdapException e )
|
||||||
|
{
|
||||||
|
throw new MappingException( e.getMessage( ), e );
|
||||||
|
}
|
||||||
|
catch ( NamingException e )
|
||||||
|
{
|
||||||
|
throw new MappingException( e.getMessage( ), e );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
close( namingEnumeration );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LdapGroup getGroupFromResult(SearchResult searchResult) throws NamingException
|
||||||
|
{
|
||||||
|
LdapGroup group = new LdapGroup( searchResult.getNameInNamespace() );
|
||||||
|
Attribute attValue = searchResult.getAttributes( ).get( groupNameAttribute );
|
||||||
|
if ( attValue != null )
|
||||||
|
{
|
||||||
|
group.setName( attValue.get( ).toString( ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.error( "Could not get group name from attribute {}. Group DN: {}", groupNameAttribute, searchResult.getNameInNamespace( ) );
|
||||||
|
}
|
||||||
|
attValue = searchResult.getAttributes( ).get( descriptionAttribute );
|
||||||
|
if (attValue!=null) {
|
||||||
|
group.setDescription( attValue.get( ).toString( ) );
|
||||||
|
}
|
||||||
|
Attribute memberValues = searchResult.getAttributes( ).get( ldapGroupMemberAttribute );
|
||||||
|
if (memberValues!=null)
|
||||||
|
{
|
||||||
|
NamingEnumeration<?> allMembersEnum = memberValues.getAll( );
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while ( allMembersEnum.hasMore( ) )
|
||||||
|
{
|
||||||
|
String memberValue = allMembersEnum.next( ).toString( );
|
||||||
|
if ( !StringUtils.isEmpty( memberValue ) )
|
||||||
|
{
|
||||||
|
group.addMember( memberValue );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
if (allMembersEnum!=null) {
|
||||||
|
closeNamingEnumeration( allMembersEnum );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
protected void closeNamingEnumeration( NamingEnumeration namingEnumeration )
|
protected void closeNamingEnumeration( NamingEnumeration namingEnumeration )
|
||||||
{
|
{
|
||||||
if ( namingEnumeration != null )
|
if ( namingEnumeration != null )
|
||||||
|
@ -379,6 +471,9 @@ public class DefaultLdapRoleMapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Should use LDAP search, as this may not work for users in subtrees
|
||||||
|
*/
|
||||||
private String getUserDnFromId(String userKey) {
|
private String getUserDnFromId(String userKey) {
|
||||||
return new StringBuilder().append( this.userIdAttribute ).append( "=" ).append( userKey ).append( "," ).append(
|
return new StringBuilder().append( this.userIdAttribute ).append( "=" ).append( userKey ).append( "," ).append(
|
||||||
getBaseDn( ) ).toString();
|
getBaseDn( ) ).toString();
|
||||||
|
@ -407,6 +502,7 @@ public class DefaultLdapRoleMapper
|
||||||
User user = userManager.findUser( username );
|
User user = userManager.findUser( username );
|
||||||
if ( user != null && user instanceof LdapUser )
|
if ( user != null && user instanceof LdapUser )
|
||||||
{
|
{
|
||||||
|
// TODO: This is some kind of memberOf retrieval, but will not work. Need to setup a memberOf Attribute
|
||||||
LdapUser ldapUser = (LdapUser) user ;
|
LdapUser ldapUser = (LdapUser) user ;
|
||||||
Attribute dnAttribute = ldapUser.getOriginalAttributes( ).get( getLdapDnAttribute( ) );
|
Attribute dnAttribute = ldapUser.getOriginalAttributes( ).get( getLdapDnAttribute( ) );
|
||||||
if ( dnAttribute != null )
|
if ( dnAttribute != null )
|
||||||
|
@ -476,6 +572,98 @@ public class DefaultLdapRoleMapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: We should implement recursive group retrieval
|
||||||
|
* Need a configuration flag, to activate recursion
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<LdapGroup> getGroupObjects( String username, DirContext context ) throws MappingException
|
||||||
|
{
|
||||||
|
Set<LdapGroup> userGroups = new HashSet<>( );
|
||||||
|
|
||||||
|
NamingEnumeration<SearchResult> namingEnumeration = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
SearchControls searchControls = new SearchControls( );
|
||||||
|
|
||||||
|
searchControls.setDerefLinkFlag( true );
|
||||||
|
searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
|
||||||
|
|
||||||
|
|
||||||
|
String userIdentifier = null;
|
||||||
|
String userDn = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//try to look the user up
|
||||||
|
User user = userManager.findUser( username );
|
||||||
|
if ( user != null && user instanceof LdapUser )
|
||||||
|
{
|
||||||
|
// TODO: This is some kind of memberOf retrieval, but will not work with DN.
|
||||||
|
// We need a configuration entry for the memberOf attribute and a flag, if this should be used
|
||||||
|
LdapUser ldapUser = (LdapUser) user ;
|
||||||
|
Attribute dnAttribute = ldapUser.getOriginalAttributes( ).get( getLdapDnAttribute( ) );
|
||||||
|
if ( dnAttribute != null )
|
||||||
|
{
|
||||||
|
userIdentifier = dnAttribute.get( ).toString();
|
||||||
|
}
|
||||||
|
userDn = ldapUser.getDn( );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( UserNotFoundException e )
|
||||||
|
{
|
||||||
|
log.warn( "Failed to look up user {}. Computing distinguished name manually", username, e );
|
||||||
|
}
|
||||||
|
catch ( UserManagerException e )
|
||||||
|
{
|
||||||
|
log.warn( "Failed to look up user {}. Computing distinguished name manually", username, e );
|
||||||
|
}
|
||||||
|
if ( userIdentifier == null )
|
||||||
|
{
|
||||||
|
//failed to look up the user's groupEntry directly
|
||||||
|
|
||||||
|
if ( this.useDnAsMemberValue )
|
||||||
|
{
|
||||||
|
userIdentifier = userDn;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
userIdentifier = username;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String filter =
|
||||||
|
new StringBuilder( ).append( "(&" ).append( "(objectClass=" + getLdapGroupClass( ) + ")" ).append(
|
||||||
|
"(" ).append( getLdapGroupMemberAttribute( ) ).append( "=" ).append( Rdn.escapeValue( userIdentifier ) ).append( ")" ).append(
|
||||||
|
")" ).toString( );
|
||||||
|
|
||||||
|
log.debug( "filter: {}", filter );
|
||||||
|
|
||||||
|
namingEnumeration = context.search( getGroupsDn( ), filter, searchControls );
|
||||||
|
|
||||||
|
while ( namingEnumeration.hasMore( ) )
|
||||||
|
{
|
||||||
|
SearchResult groupSearchResult = namingEnumeration.next( );
|
||||||
|
LdapGroup groupName = getGroupFromResult( groupSearchResult );
|
||||||
|
userGroups.add( groupName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( LdapException e )
|
||||||
|
{
|
||||||
|
throw new MappingException( e.getMessage( ), e );
|
||||||
|
}
|
||||||
|
catch ( NamingException e )
|
||||||
|
{
|
||||||
|
throw new MappingException( e.getMessage( ), e );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
close( namingEnumeration );
|
||||||
|
}
|
||||||
|
return new ArrayList( userGroups );
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getRoles( String username, DirContext context, Collection<String> realRoles )
|
public List<String> getRoles( String username, DirContext context, Collection<String> realRoles )
|
||||||
throws MappingException
|
throws MappingException
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -109,4 +110,18 @@ public class DefaultLdapRoleMapperConfiguration
|
||||||
Map<String, Collection<String>> mappings = map.asMap();
|
Map<String, Collection<String>> mappings = map.asMap();
|
||||||
return mappings;
|
return mappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> getLdapGroupMapping( String groupName ) throws MappingException
|
||||||
|
{
|
||||||
|
if (this.ldapMappings.containsKey( groupName )) {
|
||||||
|
return this.ldapMappings.get( groupName );
|
||||||
|
} else {
|
||||||
|
String value = userConf.getString( UserConfigurationKeys.LDAP_GROUPS_ROLE_START_KEY + groupName );
|
||||||
|
if ( value != null) {
|
||||||
|
return Arrays.asList( StringUtils.split( "," ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new MappingException( "Mapping for group " + groupName + " not found" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
package org.apache.archiva.redback.common.ldap.role;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representation of a LDAP group
|
||||||
|
* @author Martin Stockhammer <martin_s@apache.org>
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
public class LdapGroup
|
||||||
|
{
|
||||||
|
String dn = "";
|
||||||
|
String name;
|
||||||
|
String description;
|
||||||
|
List<String> memberList;
|
||||||
|
|
||||||
|
public LdapGroup( )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public LdapGroup( String dn )
|
||||||
|
{
|
||||||
|
this.dn = dn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LdapGroup( String dn, String name, String displayName, String description )
|
||||||
|
{
|
||||||
|
this.dn = dn;
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDn( )
|
||||||
|
{
|
||||||
|
return dn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDn( String dn )
|
||||||
|
{
|
||||||
|
this.dn = dn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName( )
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName( String name )
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription( )
|
||||||
|
{
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription( String description )
|
||||||
|
{
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMember(String member) {
|
||||||
|
if (this.memberList==null) {
|
||||||
|
this.memberList = new ArrayList<>( );
|
||||||
|
}
|
||||||
|
this.memberList.add( member );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMemberList( Collection<String> memberList) {
|
||||||
|
this.memberList = new ArrayList<>( memberList );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getMemberList() {
|
||||||
|
return memberList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals( Object o )
|
||||||
|
{
|
||||||
|
if ( this == o ) return true;
|
||||||
|
if ( o == null || getClass( ) != o.getClass( ) ) return false;
|
||||||
|
|
||||||
|
LdapGroup ldapGroup = (LdapGroup) o;
|
||||||
|
|
||||||
|
return dn.equals( ldapGroup.dn );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode( )
|
||||||
|
{
|
||||||
|
return dn.hashCode( );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString( )
|
||||||
|
{
|
||||||
|
final StringBuilder sb = new StringBuilder( "LdapGroup{" );
|
||||||
|
sb.append( "dn='" ).append( dn ).append( '\'' );
|
||||||
|
sb.append( ", name='" ).append( name ).append( '\'' );
|
||||||
|
sb.append( '}' );
|
||||||
|
return sb.toString( );
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,6 +42,14 @@ public interface LdapRoleMapper
|
||||||
List<String> getAllGroups( DirContext context )
|
List<String> getAllGroups( DirContext context )
|
||||||
throws MappingException;
|
throws MappingException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read all groups from ldap
|
||||||
|
*
|
||||||
|
* @return all LDAP groups
|
||||||
|
*/
|
||||||
|
List<LdapGroup> getAllGroupObjects( DirContext context )
|
||||||
|
throws MappingException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read all ldap groups then map to corresponding role (if no mapping found group is ignored)
|
* read all ldap groups then map to corresponding role (if no mapping found group is ignored)
|
||||||
*
|
*
|
||||||
|
@ -76,6 +84,9 @@ public interface LdapRoleMapper
|
||||||
List<String> getGroups( String username, DirContext context )
|
List<String> getGroups( String username, DirContext context )
|
||||||
throws MappingException;
|
throws MappingException;
|
||||||
|
|
||||||
|
List<LdapGroup> getGroupObjects( String username, DirContext context )
|
||||||
|
throws MappingException;
|
||||||
|
|
||||||
List<String> getRoles( String username, DirContext context, Collection<String> realRoles )
|
List<String> getRoles( String username, DirContext context, Collection<String> realRoles )
|
||||||
throws MappingException;
|
throws MappingException;
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,14 @@ public interface LdapRoleMapperConfiguration
|
||||||
Map<String, Collection<String>> getLdapGroupMappings()
|
Map<String, Collection<String>> getLdapGroupMappings()
|
||||||
throws MappingException;
|
throws MappingException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the mapping for the given group
|
||||||
|
* @param groupName the group name
|
||||||
|
* @return the list of roles
|
||||||
|
* @throws MappingException
|
||||||
|
*/
|
||||||
|
Collection<String> getLdapGroupMapping(String groupName) throws MappingException;
|
||||||
|
|
||||||
void setLdapGroupMappings( Map<String, List<String>> mappings )
|
void setLdapGroupMappings( Map<String, List<String>> mappings )
|
||||||
throws MappingException;
|
throws MappingException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import java.util.List;
|
||||||
public class LdapUser
|
public class LdapUser
|
||||||
implements User, Serializable
|
implements User, Serializable
|
||||||
{
|
{
|
||||||
|
private String dn;
|
||||||
|
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
|
@ -249,4 +250,13 @@ public class LdapUser
|
||||||
return userManagerId;
|
return userManagerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDn( )
|
||||||
|
{
|
||||||
|
return dn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDn( String dn )
|
||||||
|
{
|
||||||
|
this.dn = dn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ public class LdapUserMapper
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LdapUser getUser( Attributes attributes )
|
public LdapUser getUser( String dn, Attributes attributes )
|
||||||
throws MappingException
|
throws MappingException
|
||||||
{
|
{
|
||||||
String userIdAttribute = getUserIdAttribute();
|
String userIdAttribute = getUserIdAttribute();
|
||||||
|
@ -191,6 +191,7 @@ public class LdapUserMapper
|
||||||
String userId = LdapUtils.getAttributeValue( attributes, userIdAttribute, "username" );
|
String userId = LdapUtils.getAttributeValue( attributes, userIdAttribute, "username" );
|
||||||
|
|
||||||
LdapUser user = new LdapUser( userId );
|
LdapUser user = new LdapUser( userId );
|
||||||
|
user.setDn( dn );
|
||||||
user.setOriginalAttributes( attributes );
|
user.setOriginalAttributes( attributes );
|
||||||
|
|
||||||
user.setEmail( LdapUtils.getAttributeValue( attributes, emailAddressAttribute, "email address" ) );
|
user.setEmail( LdapUtils.getAttributeValue( attributes, emailAddressAttribute, "email address" ) );
|
||||||
|
|
|
@ -29,7 +29,7 @@ import javax.naming.directory.Attributes;
|
||||||
*/
|
*/
|
||||||
public interface UserMapper
|
public interface UserMapper
|
||||||
{
|
{
|
||||||
LdapUser getUser( Attributes attributes )
|
LdapUser getUser( String dn, Attributes attributes )
|
||||||
throws MappingException;
|
throws MappingException;
|
||||||
|
|
||||||
Attributes getCreationAttributes( User user, boolean encodePasswordIfChanged )
|
Attributes getCreationAttributes( User user, boolean encodePasswordIfChanged )
|
||||||
|
|
|
@ -100,6 +100,8 @@ public interface UserConfigurationKeys
|
||||||
|
|
||||||
String LDAP_GROUP_NAME_ATTRIBUTE = "ldap.config.groups.name.attribute";
|
String LDAP_GROUP_NAME_ATTRIBUTE = "ldap.config.groups.name.attribute";
|
||||||
|
|
||||||
|
String LDAP_GROUP_DESCRIPTION_ATTRIBUTE = "ldap.config.groups.description.attribute";
|
||||||
|
|
||||||
String APPLICATION_URL = "application.url";
|
String APPLICATION_URL = "application.url";
|
||||||
|
|
||||||
String EMAIL_URL_PATH = "email.url.path";
|
String EMAIL_URL_PATH = "email.url.path";
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
package org.apache.archiva.redback.rest.api.model;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Martin Stockhammer <martin_s@apache.org>
|
||||||
|
*/
|
||||||
|
@XmlRootElement(name="group")
|
||||||
|
public class Group
|
||||||
|
{
|
||||||
|
String name;
|
||||||
|
String uniqueName;
|
||||||
|
String description;
|
||||||
|
List<String> memberList;
|
||||||
|
|
||||||
|
public Group() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Group( String name )
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName( )
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName( String name )
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUniqueName( )
|
||||||
|
{
|
||||||
|
return uniqueName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUniqueName( String uniqueName )
|
||||||
|
{
|
||||||
|
this.uniqueName = uniqueName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription( )
|
||||||
|
{
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription( String description )
|
||||||
|
{
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getMemberList( )
|
||||||
|
{
|
||||||
|
return memberList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMemberList( List<String> memberList )
|
||||||
|
{
|
||||||
|
this.memberList = memberList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMember(String member) {
|
||||||
|
if (this.memberList==null) {
|
||||||
|
this.memberList = new ArrayList<>( );
|
||||||
|
}
|
||||||
|
this.memberList.add( member );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
package org.apache.archiva.redback.rest.api.model;
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Olivier Lamy
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
@XmlRootElement(name = "groupMapping")
|
||||||
|
public class GroupMapping
|
||||||
|
implements Serializable
|
||||||
|
{
|
||||||
|
private String group;
|
||||||
|
|
||||||
|
private Collection<String> roleNames;
|
||||||
|
|
||||||
|
public GroupMapping()
|
||||||
|
{
|
||||||
|
// no op
|
||||||
|
}
|
||||||
|
|
||||||
|
public GroupMapping( String group, Collection<String> roleNames )
|
||||||
|
{
|
||||||
|
this.group = group;
|
||||||
|
this.roleNames = roleNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGroup()
|
||||||
|
{
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroup( String group )
|
||||||
|
{
|
||||||
|
this.group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<String> getRoleNames()
|
||||||
|
{
|
||||||
|
return roleNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoleNames( Collection<String> roleNames )
|
||||||
|
{
|
||||||
|
this.roleNames = roleNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append( "LdapGroupMapping" );
|
||||||
|
sb.append( "{group='" ).append( group ).append( '\'' );
|
||||||
|
sb.append( ", roleNames=" ).append( roleNames );
|
||||||
|
sb.append( '}' );
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals( Object o )
|
||||||
|
{
|
||||||
|
if ( this == o )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( o == null || getClass() != o.getClass() )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupMapping that = (GroupMapping) o;
|
||||||
|
|
||||||
|
if ( !group.equals( that.group ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return group.hashCode();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package org.apache.archiva.redback.rest.api.model;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Olivier Lamy
|
||||||
|
*/
|
||||||
|
@XmlRootElement( name = "groupMappingUpdateRequest" )
|
||||||
|
public class GroupMappingUpdateRequest
|
||||||
|
implements Serializable
|
||||||
|
{
|
||||||
|
|
||||||
|
private List<GroupMapping> groupMapping;
|
||||||
|
|
||||||
|
public GroupMappingUpdateRequest()
|
||||||
|
{
|
||||||
|
// no op
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GroupMapping> getGroupMapping()
|
||||||
|
{
|
||||||
|
if ( this.groupMapping == null )
|
||||||
|
{
|
||||||
|
this.groupMapping = new ArrayList<GroupMapping>();
|
||||||
|
}
|
||||||
|
return groupMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroupMapping( List<GroupMapping> groupMapping )
|
||||||
|
{
|
||||||
|
this.groupMapping = groupMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
final StringBuilder sb = new StringBuilder( "LdapGroupMappingUpdateRequest{" );
|
||||||
|
sb.append( "ldapGroupMapping=" ).append( groupMapping );
|
||||||
|
sb.append( '}' );
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,6 +43,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Path("/ldapGroupMappingService/")
|
@Path("/ldapGroupMappingService/")
|
||||||
@Tag( name = "LDAP", description = "LDAP Service" )
|
@Tag( name = "LDAP", description = "LDAP Service" )
|
||||||
|
@Deprecated
|
||||||
public interface LdapGroupMappingService
|
public interface LdapGroupMappingService
|
||||||
{
|
{
|
||||||
@Path("ldapGroups")
|
@Path("ldapGroups")
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
package org.apache.archiva.redback.rest.api.services.v2;
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.apache.archiva.redback.authorization.RedbackAuthorization;
|
||||||
|
import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.ActionStatus;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.Group;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.GroupMapping;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.GroupMappingUpdateRequest;
|
||||||
|
import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.DefaultValue;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Olivier Lamy
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
@Path( "/groups" )
|
||||||
|
@Tag( name = "Groups", description = "Groups and Group to Role Mappings" )
|
||||||
|
public interface GroupService
|
||||||
|
{
|
||||||
|
|
||||||
|
@Path( "" )
|
||||||
|
@GET
|
||||||
|
@Produces( {MediaType.APPLICATION_JSON} )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.CONFIGURATION_EDIT_OPERATION )
|
||||||
|
@Operation( summary = "Get list of group objects",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse( description = "List of group objects. The number of returned results depend on the pagination parameters offset and limit." )
|
||||||
|
}
|
||||||
|
)
|
||||||
|
List<Group> getGroups( @QueryParam( "offset" ) @DefaultValue( "0" ) Long offset,
|
||||||
|
@QueryParam( "limit" ) @DefaultValue( value = Long.MAX_VALUE+"" ) Long limit)
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
@Path( "mappings" )
|
||||||
|
@GET
|
||||||
|
@Produces( {MediaType.APPLICATION_JSON} )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.CONFIGURATION_EDIT_OPERATION )
|
||||||
|
@Operation( summary = "Get list of group mappings",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse( description = "List of group mappings" )
|
||||||
|
}
|
||||||
|
)
|
||||||
|
List<GroupMapping> getGroupMappings( )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
@Path( "mappings" )
|
||||||
|
@POST
|
||||||
|
@Consumes( {MediaType.APPLICATION_JSON} )
|
||||||
|
@Produces( {MediaType.APPLICATION_JSON} )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.CONFIGURATION_EDIT_OPERATION )
|
||||||
|
@Operation( summary = "Adds a group mapping",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse( description = "The status of the add action" ),
|
||||||
|
@ApiResponse( responseCode = "405", description = "Invalid input" )
|
||||||
|
}
|
||||||
|
)
|
||||||
|
ActionStatus addGroupMapping( @Parameter( description = "The data of the group mapping", required = true )
|
||||||
|
GroupMapping groupMapping )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
@Path( "mappings/{group}" )
|
||||||
|
@DELETE
|
||||||
|
@Consumes( {MediaType.APPLICATION_JSON} )
|
||||||
|
@Produces( {MediaType.APPLICATION_JSON} )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.CONFIGURATION_EDIT_OPERATION )
|
||||||
|
@Operation( summary = "Deletes a group mapping",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse( description = "The status of the delete action" ),
|
||||||
|
@ApiResponse( responseCode = "404", description = "Group mapping not found" )
|
||||||
|
}
|
||||||
|
)
|
||||||
|
ActionStatus removeGroupMapping( @Parameter( description = "The group name", required = true )
|
||||||
|
@PathParam( "group" ) String group )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
@Path( "mappings/{group}" )
|
||||||
|
@PUT
|
||||||
|
@Consumes( {MediaType.APPLICATION_JSON} )
|
||||||
|
@Produces( {MediaType.APPLICATION_JSON} )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.CONFIGURATION_EDIT_OPERATION )
|
||||||
|
@Operation( summary = "Updates a group mapping",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse( description = "The status of the update action" ),
|
||||||
|
@ApiResponse( responseCode = "404", description = "Group mapping not found" )
|
||||||
|
}
|
||||||
|
)
|
||||||
|
ActionStatus updateGroupMapping( @Parameter( description = "The group name", required = true )
|
||||||
|
@PathParam( "group" ) String groupName,
|
||||||
|
@Parameter( description = "The updated data of the group mapping", required = true )
|
||||||
|
GroupMapping groupMapping )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
@Path( "mappings" )
|
||||||
|
@PUT
|
||||||
|
@Consumes( {MediaType.APPLICATION_JSON} )
|
||||||
|
@Produces( {MediaType.APPLICATION_JSON} )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.CONFIGURATION_EDIT_OPERATION )
|
||||||
|
@Operation( summary = "Updates a multiple group mappings",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse( description = "The status of the update action" ),
|
||||||
|
@ApiResponse( responseCode = "405", description = "Invalid input" )
|
||||||
|
}
|
||||||
|
)
|
||||||
|
ActionStatus updateGroupMapping( @Parameter( description = "The list of group mapping updates", required = true )
|
||||||
|
GroupMappingUpdateRequest groupMappingUpdateRequest )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
package org.apache.archiva.redback.rest.api.services.v2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.archiva.redback.authorization.RedbackAuthorization;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.ActionStatus;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.AuthenticationKeyResult;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.LoginRequest;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.PingResult;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.User;
|
||||||
|
import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
|
||||||
|
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
@Path( "/auth" )
|
||||||
|
public interface LoginService
|
||||||
|
{
|
||||||
|
|
||||||
|
@Path( "requestkey" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( noRestriction = true )
|
||||||
|
AuthenticationKeyResult addAuthenticationKey( @QueryParam( "providerKey" ) String providedKey,
|
||||||
|
@QueryParam( "principal" ) String principal, @QueryParam( "purpose" ) String purpose,
|
||||||
|
@QueryParam( "expirationMinutes" ) int expirationMinutes )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
@Path( "ping" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( noRestriction = true )
|
||||||
|
PingResult ping()
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
@Path( "ping/authenticated" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( noRestriction = false, noPermission = true )
|
||||||
|
PingResult pingWithAutz()
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check username/password and create a http session.
|
||||||
|
* So no more need of reuse username/password for all ajaxRequest
|
||||||
|
*/
|
||||||
|
@Path( "authenticate" )
|
||||||
|
@POST
|
||||||
|
@RedbackAuthorization( noRestriction = true, noPermission = true )
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
User logIn( LoginRequest loginRequest )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* simply check if current user has an http session opened with authz passed and return user data
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Path( "isAuthenticated" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
|
||||||
|
@RedbackAuthorization( noRestriction = true )
|
||||||
|
User isLogged()
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clear user http session
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Path( "logout" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( noRestriction = true, noPermission = true )
|
||||||
|
ActionStatus logout()
|
||||||
|
throws RedbackServiceException;
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package org.apache.archiva.redback.rest.api.services.v2;
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.archiva.redback.authorization.RedbackAuthorization;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.User;
|
||||||
|
import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
|
||||||
|
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Olivier Lamy
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Path( "/passwordService/" )
|
||||||
|
public interface PasswordService
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used to change the password on first user connection after registration use.
|
||||||
|
* the key is mandatory and a control will be done on the username provided.
|
||||||
|
* <b>need to be logged by {@link UserService#validateUserFromKey(String)}</b>
|
||||||
|
* @return username
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path( "changePasswordWithKey" )
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( noRestriction = true, noPermission = true )
|
||||||
|
User changePasswordWithKey( @QueryParam( "password" ) String password,
|
||||||
|
@QueryParam( "passwordConfirmation" ) String passwordConfirmation,
|
||||||
|
@QueryParam( "key" ) String key )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used to change the password on passwordChangeRequired state.
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path( "changePassword" )
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( noRestriction = true, noPermission = true )
|
||||||
|
User changePassword( @QueryParam( "userName" ) String userName,
|
||||||
|
@QueryParam( "previousPassword" ) String previousPassword,
|
||||||
|
@QueryParam( "password" ) String password,
|
||||||
|
@QueryParam( "passwordConfirmation" ) String passwordConfirmation )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
}
|
|
@ -0,0 +1,310 @@
|
||||||
|
package org.apache.archiva.redback.rest.api.services.v2;
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.archiva.redback.authorization.RedbackAuthorization;
|
||||||
|
import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.ActionStatus;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.Application;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.ApplicationRoles;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.AvailabilityStatus;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.Role;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.User;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.VerificationStatus;
|
||||||
|
import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Olivier Lamy
|
||||||
|
*/
|
||||||
|
@Path( "/roleManagementService/" )
|
||||||
|
public interface RoleManagementService
|
||||||
|
{
|
||||||
|
|
||||||
|
@Path( "createTemplatedRole" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
ActionStatus createTemplatedRole( @QueryParam( "templateId" ) String templateId,
|
||||||
|
@QueryParam( "resource" ) String resource )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removes a role corresponding to the role Id that was manufactured with the given resource
|
||||||
|
*
|
||||||
|
* it also removes any user assignments for that role
|
||||||
|
*
|
||||||
|
* @param templateId
|
||||||
|
* @param resource
|
||||||
|
*/
|
||||||
|
@Path( "removeTemplatedRole" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
ActionStatus removeTemplatedRole( @QueryParam( "templateId" ) String templateId,
|
||||||
|
@QueryParam( "resource" ) String resource )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* allows for a role coming from a template to be renamed effectively swapping out the bits of it that
|
||||||
|
* were labeled with the oldResource with the newResource
|
||||||
|
*
|
||||||
|
* it also manages any user assignments for that role
|
||||||
|
*
|
||||||
|
* @param templateId
|
||||||
|
* @param oldResource
|
||||||
|
* @param newResource
|
||||||
|
*/
|
||||||
|
@Path( "updateRole" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
ActionStatus updateRole( @QueryParam( "templateId" ) String templateId, @QueryParam( "oldResource" ) String oldResource,
|
||||||
|
@QueryParam( "newResource" ) String newResource )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns the role indicated by the roleId to the given principal
|
||||||
|
*
|
||||||
|
* @param roleId
|
||||||
|
* @param principal
|
||||||
|
*/
|
||||||
|
@Path( "assignRole" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
ActionStatus assignRole( @QueryParam( "roleId" ) String roleId, @QueryParam( "principal" ) String principal )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns the role indicated by the roleName to the given principal
|
||||||
|
*
|
||||||
|
* @param roleName
|
||||||
|
* @param principal
|
||||||
|
* @throws RedbackServiceException
|
||||||
|
*/
|
||||||
|
@Path( "assignRoleByName" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
ActionStatus assignRoleByName( @QueryParam( "roleName" ) String roleName, @QueryParam( "principal" ) String principal )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns the templated role indicated by the templateId
|
||||||
|
*
|
||||||
|
* fails if the templated role has not been created
|
||||||
|
*
|
||||||
|
* @param templateId
|
||||||
|
* @param resource
|
||||||
|
* @param principal
|
||||||
|
*/
|
||||||
|
@Path( "assignTemplatedRole" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
ActionStatus assignTemplatedRole( @QueryParam( "templateId" ) String templateId,
|
||||||
|
@QueryParam( "resource" ) String resource,
|
||||||
|
@QueryParam( "principal" ) String principal )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unassigns the role indicated by the role id from the given principal
|
||||||
|
*
|
||||||
|
* @param roleId
|
||||||
|
* @param principal
|
||||||
|
* @throws RedbackServiceException
|
||||||
|
*/
|
||||||
|
@Path( "unassignRole" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
ActionStatus unassignRole( @QueryParam( "roleId" ) String roleId, @QueryParam( "principal" ) String principal )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unassigns the role indicated by the role name from the given principal
|
||||||
|
*
|
||||||
|
* @param roleName
|
||||||
|
* @param principal
|
||||||
|
* @throws RedbackServiceException
|
||||||
|
*/
|
||||||
|
@Path( "unassignRoleByName" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
ActionStatus unassignRoleByName( @QueryParam( "roleName" ) String roleName, @QueryParam( "principal" ) String principal )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* true of a role exists with the given roleId
|
||||||
|
*
|
||||||
|
* @param roleId
|
||||||
|
* @return
|
||||||
|
* @throws RedbackServiceException
|
||||||
|
*/
|
||||||
|
@Path( "roleExists" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
AvailabilityStatus roleExists( @QueryParam( "roleId" ) String roleId )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* true of a role exists with the given roleId
|
||||||
|
*
|
||||||
|
* @param templateId
|
||||||
|
* @param resource
|
||||||
|
* @return
|
||||||
|
* @throws RedbackServiceException
|
||||||
|
*/
|
||||||
|
@Path( "templatedRoleExists" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
AvailabilityStatus templatedRoleExists( @QueryParam( "templateId" ) String templateId,
|
||||||
|
@QueryParam( "resource" ) String resource )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check a role template is complete in the RBAC store.
|
||||||
|
*
|
||||||
|
* @param templateId the templated role
|
||||||
|
* @param resource the resource to verify
|
||||||
|
* @throws RedbackServiceException
|
||||||
|
*/
|
||||||
|
@Path( "verifyTemplatedRole" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
VerificationStatus verifyTemplatedRole( @QueryParam( "templateId" ) String templateId,
|
||||||
|
@QueryParam( "resource" ) String resource )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Path( "getEffectivelyAssignedRoles/{username}" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
List<Role> getEffectivelyAssignedRoles( @PathParam( "username" ) String username )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
@Path( "allRoles" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
List<Role> getAllRoles()
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
@Path( "detailledAllRoles" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
List<Role> getDetailedAllRoles()
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
@Path( "getApplications/{username}" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
List<Application> getApplications( @PathParam( "username" ) String username )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
@Path( "getRole/{roleName}" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
Role getRole( @PathParam( "roleName" ) String roleName )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
@Path( "updateRoleDescription" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
ActionStatus updateRoleDescription( @QueryParam( "roleName" ) String roleName,
|
||||||
|
@QueryParam( "roleDescription" ) String description )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update users assigned to a role
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
@Path( "updateRoleUsers" )
|
||||||
|
@POST
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
|
||||||
|
@Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
ActionStatus updateRoleUsers( Role role )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
@Path( "getApplicationRoles/{username}" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
List<ApplicationRoles> getApplicationRoles( @PathParam( "username" ) String username )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update roles assigned to a user
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
@Path( "updateUserRoles" )
|
||||||
|
@POST
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
|
||||||
|
@Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
|
||||||
|
ActionStatus updateUserRoles( User user )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,258 @@
|
||||||
|
package org.apache.archiva.redback.rest.api.services.v2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.archiva.redback.authorization.RedbackAuthorization;
|
||||||
|
import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.ActionStatus;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.AvailabilityStatus;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.Operation;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.PasswordStatus;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.Permission;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.PingResult;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.RegistrationKey;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.ResetPasswordRequest;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.User;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.UserRegistrationRequest;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.VerificationStatus;
|
||||||
|
import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Path( "/userService/" )
|
||||||
|
public interface UserService
|
||||||
|
{
|
||||||
|
@Path( "getUser/{userName}" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_EDIT_OPERATION )
|
||||||
|
User getUser( @PathParam( "userName" ) String username )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
@Path( "getUsers" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_LIST_OPERATION )
|
||||||
|
List<User> getUsers()
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
@Path( "createUser" )
|
||||||
|
@POST
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_CREATE_OPERATION )
|
||||||
|
ActionStatus createUser( User user )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* will create admin user only if not exists !! if exists will return false
|
||||||
|
*/
|
||||||
|
@Path( "createAdminUser" )
|
||||||
|
@POST
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
|
||||||
|
@RedbackAuthorization( noRestriction = true )
|
||||||
|
ActionStatus createAdminUser( User user )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
@Path( "isAdminUserExists" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( noRestriction = true )
|
||||||
|
AvailabilityStatus isAdminUserExists()
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
@Path( "deleteUser/{userName}" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_DELETE_OPERATION )
|
||||||
|
ActionStatus deleteUser( @PathParam( "userName" ) String username )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
@Path( "updateUser" )
|
||||||
|
@POST
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_EDIT_OPERATION )
|
||||||
|
ActionStatus updateUser( User user )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
@Path( "lockUser/{username}" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_EDIT_OPERATION )
|
||||||
|
ActionStatus lockUser( @PathParam( "username" ) String username )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
@Path( "unlockUser/{username}" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_EDIT_OPERATION )
|
||||||
|
ActionStatus unlockUser( @PathParam( "username" ) String username )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
@Path( "passwordChangeRequired/{username}" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_EDIT_OPERATION )
|
||||||
|
PasswordStatus passwordChangeRequired( @PathParam( "username" ) String username )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update only the current user and this fields: fullname, email, password.
|
||||||
|
* the service verify the curent logged user with the one passed in the method
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Path( "updateMe" )
|
||||||
|
@POST
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( noRestriction = false, noPermission = true )
|
||||||
|
ActionStatus updateMe( User user )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
@Path( "ping" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( noRestriction = true )
|
||||||
|
PingResult ping()
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
@Path( "removeFromCache/{userName}" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_EDIT_OPERATION )
|
||||||
|
ActionStatus removeFromCache( @PathParam( "userName" ) String username )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
@Path( "getGuestUser" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_EDIT_OPERATION )
|
||||||
|
User getGuestUser()
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
@Path( "createGuestUser" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_EDIT_OPERATION )
|
||||||
|
User createGuestUser()
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if redback is not configured for email validation is required, -1 is returned as key
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Path( "registerUser" )
|
||||||
|
@POST
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
|
||||||
|
@RedbackAuthorization( noRestriction = true, noPermission = true )
|
||||||
|
RegistrationKey registerUser( UserRegistrationRequest userRegistrationRequest )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate the key and the user with forcing a password change for next login.
|
||||||
|
* http session is created.
|
||||||
|
* @param key authentication key
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Path( "validateKey/{key}" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( noRestriction = true, noPermission = true )
|
||||||
|
VerificationStatus validateUserFromKey( @PathParam( "key" ) String key )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param resetPasswordRequest contains username for send a password reset email
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Path( "resetPassword" )
|
||||||
|
@POST
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
|
||||||
|
@RedbackAuthorization( noRestriction = true, noPermission = true )
|
||||||
|
ActionStatus resetPassword( ResetPasswordRequest resetPasswordRequest )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Path( "getUserPermissions/{userName}" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_LIST_OPERATION )
|
||||||
|
Collection<Permission> getUserPermissions( @PathParam( "userName" ) String userName )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Path( "getUserOperations/{userName}" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_USER_LIST_OPERATION )
|
||||||
|
Collection<Operation> getUserOperations( @PathParam( "userName" ) String userName )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the current logged user permissions, if no logged user guest permissions are returned
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Path( "getCurrentUserPermissions" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( noRestriction = true, noPermission = true )
|
||||||
|
Collection<Permission> getCurrentUserPermissions()
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the current logged user operations, if no logged user guest operations are returned
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Path( "getCurrentUserOperations" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( noRestriction = true, noPermission = true )
|
||||||
|
Collection<Operation> getCurrentUserOperations()
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package org.apache.archiva.redback.rest.api.services.v2;
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.archiva.redback.authorization.RedbackAuthorization;
|
||||||
|
import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
|
||||||
|
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Olivier Lamy
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
@Path( "/utilServices/" )
|
||||||
|
public interface UtilServices
|
||||||
|
{
|
||||||
|
|
||||||
|
@Path( "getBundleResources" )
|
||||||
|
@GET
|
||||||
|
@Produces( { MediaType.TEXT_PLAIN } )
|
||||||
|
@RedbackAuthorization( noRestriction = true )
|
||||||
|
String getI18nResources( @QueryParam( "locale" ) String locale )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>not intended to be exposed as a REST service.</b>
|
||||||
|
* will load i18N resource org/apache/archiva/redback/users/messages in default en then in the asked locale.
|
||||||
|
* @param locale
|
||||||
|
* @return
|
||||||
|
* @throws RedbackServiceException
|
||||||
|
*/
|
||||||
|
Properties getI18nProperties( String locale )
|
||||||
|
throws RedbackServiceException;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ import org.apache.archiva.redback.common.ldap.connection.LdapException;
|
||||||
import org.apache.archiva.redback.common.ldap.role.LdapRoleMapper;
|
import org.apache.archiva.redback.common.ldap.role.LdapRoleMapper;
|
||||||
import org.apache.archiva.redback.common.ldap.role.LdapRoleMapperConfiguration;
|
import org.apache.archiva.redback.common.ldap.role.LdapRoleMapperConfiguration;
|
||||||
import org.apache.archiva.redback.rest.api.model.ActionStatus;
|
import org.apache.archiva.redback.rest.api.model.ActionStatus;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.Group;
|
||||||
import org.apache.archiva.redback.rest.api.model.LdapGroupMapping;
|
import org.apache.archiva.redback.rest.api.model.LdapGroupMapping;
|
||||||
import org.apache.archiva.redback.rest.api.model.LdapGroupMappingUpdateRequest;
|
import org.apache.archiva.redback.rest.api.model.LdapGroupMappingUpdateRequest;
|
||||||
import org.apache.archiva.redback.rest.api.model.StringList;
|
import org.apache.archiva.redback.rest.api.model.StringList;
|
||||||
|
@ -42,6 +43,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Olivier Lamy
|
* @author Olivier Lamy
|
||||||
|
|
|
@ -0,0 +1,235 @@
|
||||||
|
package org.apache.archiva.redback.rest.services.v2;
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.archiva.redback.common.ldap.MappingException;
|
||||||
|
import org.apache.archiva.redback.common.ldap.connection.LdapConnection;
|
||||||
|
import org.apache.archiva.redback.common.ldap.connection.LdapConnectionFactory;
|
||||||
|
import org.apache.archiva.redback.common.ldap.connection.LdapException;
|
||||||
|
import org.apache.archiva.redback.common.ldap.role.LdapGroup;
|
||||||
|
import org.apache.archiva.redback.common.ldap.role.LdapRoleMapper;
|
||||||
|
import org.apache.archiva.redback.common.ldap.role.LdapRoleMapperConfiguration;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.ActionStatus;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.Group;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.GroupMapping;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.GroupMappingUpdateRequest;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.StringList;
|
||||||
|
import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
|
||||||
|
import org.apache.archiva.redback.rest.api.services.v2.GroupService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import javax.naming.directory.DirContext;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LDAP implementation of the group service
|
||||||
|
*
|
||||||
|
* @author Olivier Lamy
|
||||||
|
* @author Martin Stockhammer
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
@Service("v2.groupService#rest")
|
||||||
|
public class DefaultGroupService
|
||||||
|
implements GroupService
|
||||||
|
{
|
||||||
|
private final Logger log = LoggerFactory.getLogger( getClass() );
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Named(value = "ldapRoleMapper#default")
|
||||||
|
private LdapRoleMapper ldapRoleMapper;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Named(value = "ldapRoleMapperConfiguration#default")
|
||||||
|
private LdapRoleMapperConfiguration ldapRoleMapperConfiguration;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Named(value = "ldapConnectionFactory#configurable")
|
||||||
|
private LdapConnectionFactory ldapConnectionFactory;
|
||||||
|
|
||||||
|
private static final Group getGroupFromLdap( LdapGroup ldapGroup ) {
|
||||||
|
Group group = new Group( );
|
||||||
|
group.setName( ldapGroup.getName() );
|
||||||
|
group.setUniqueName( ldapGroup.getDn() );
|
||||||
|
group.setDescription( ldapGroup.getDescription() );
|
||||||
|
group.setMemberList( ldapGroup.getMemberList() );
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Group> getGroups( Long offset, Long limit ) throws RedbackServiceException
|
||||||
|
{
|
||||||
|
LdapConnection ldapConnection = null;
|
||||||
|
|
||||||
|
DirContext context = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ldapConnection = ldapConnectionFactory.getConnection();
|
||||||
|
context = ldapConnection.getDirContext();
|
||||||
|
return ldapRoleMapper.getAllGroupObjects( context ).stream( ).skip( offset ).limit( limit ).map( DefaultGroupService::getGroupFromLdap ).collect( Collectors.toList( ) );
|
||||||
|
}
|
||||||
|
catch ( LdapException | MappingException e )
|
||||||
|
{
|
||||||
|
log.error( e.getMessage(), e );
|
||||||
|
throw new RedbackServiceException( e.getMessage() );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
closeContext( context );
|
||||||
|
closeLdapConnection( ldapConnection );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<GroupMapping> getGroupMappings()
|
||||||
|
throws RedbackServiceException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Map<String, Collection<String>> map = ldapRoleMapperConfiguration.getLdapGroupMappings();
|
||||||
|
List<GroupMapping> ldapGroupMappings = new ArrayList<>( map.size( ) );
|
||||||
|
for ( Map.Entry<String, Collection<String>> entry : map.entrySet() )
|
||||||
|
{
|
||||||
|
GroupMapping ldapGroupMapping = new GroupMapping( entry.getKey(), entry.getValue() );
|
||||||
|
ldapGroupMappings.add( ldapGroupMapping );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ldapGroupMappings;
|
||||||
|
}
|
||||||
|
catch ( MappingException e )
|
||||||
|
{
|
||||||
|
log.error( e.getMessage(), e );
|
||||||
|
throw new RedbackServiceException( e.getMessage() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionStatus addGroupMapping( GroupMapping ldapGroupMapping )
|
||||||
|
throws RedbackServiceException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ldapRoleMapperConfiguration.addLdapMapping( ldapGroupMapping.getGroup(),
|
||||||
|
new ArrayList<>( ldapGroupMapping.getRoleNames() ) );
|
||||||
|
}
|
||||||
|
catch ( MappingException e )
|
||||||
|
{
|
||||||
|
log.error( e.getMessage(), e );
|
||||||
|
throw new RedbackServiceException( e.getMessage() );
|
||||||
|
}
|
||||||
|
return ActionStatus.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionStatus removeGroupMapping( String group )
|
||||||
|
throws RedbackServiceException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ldapRoleMapperConfiguration.removeLdapMapping( group );
|
||||||
|
}
|
||||||
|
catch ( MappingException e )
|
||||||
|
{
|
||||||
|
log.error( e.getMessage(), e );
|
||||||
|
throw new RedbackServiceException( e.getMessage() );
|
||||||
|
}
|
||||||
|
return ActionStatus.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionStatus updateGroupMapping( String groupName, GroupMapping groupMapping ) throws RedbackServiceException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ldapRoleMapperConfiguration.getLdapGroupMapping( groupName );
|
||||||
|
}
|
||||||
|
catch ( MappingException e )
|
||||||
|
{
|
||||||
|
throw new RedbackServiceException( "Group mapping not found ", 404 );
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ldapRoleMapperConfiguration.updateLdapMapping( groupName,
|
||||||
|
new ArrayList<>( groupMapping.getRoleNames() ) );
|
||||||
|
return ActionStatus.SUCCESS;
|
||||||
|
}
|
||||||
|
catch ( MappingException e )
|
||||||
|
{
|
||||||
|
log.error( "Could not update mapping {}", e.getMessage( ) );
|
||||||
|
throw new RedbackServiceException( e.getMessage( ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionStatus updateGroupMapping( GroupMappingUpdateRequest groupMappingUpdateRequest )
|
||||||
|
throws RedbackServiceException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for ( GroupMapping ldapGroupMapping : groupMappingUpdateRequest.getGroupMapping() )
|
||||||
|
{
|
||||||
|
ldapRoleMapperConfiguration.updateLdapMapping( ldapGroupMapping.getGroup(),
|
||||||
|
new ArrayList<>( ldapGroupMapping.getRoleNames() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( MappingException e )
|
||||||
|
{
|
||||||
|
log.error( e.getMessage(), e );
|
||||||
|
throw new RedbackServiceException( e.getMessage() );
|
||||||
|
}
|
||||||
|
return ActionStatus.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------
|
||||||
|
// utils
|
||||||
|
//------------------
|
||||||
|
|
||||||
|
protected void closeLdapConnection( LdapConnection ldapConnection )
|
||||||
|
{
|
||||||
|
if ( ldapConnection != null )
|
||||||
|
{
|
||||||
|
ldapConnection.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void closeContext( DirContext context )
|
||||||
|
{
|
||||||
|
if ( context != null )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
catch ( NamingException e )
|
||||||
|
{
|
||||||
|
log.warn( "skip issue closing context: {}", e.getMessage() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -74,4 +74,26 @@
|
||||||
</jaxrs:providers>
|
</jaxrs:providers>
|
||||||
</jaxrs:server>
|
</jaxrs:server>
|
||||||
|
|
||||||
|
<jaxrs:server address="/redback/v2">
|
||||||
|
<jaxrs:serviceBeans>
|
||||||
|
<ref bean="userService#rest"/>
|
||||||
|
<ref bean="loginService#rest"/>
|
||||||
|
<ref bean="roleManagementService#rest"/>
|
||||||
|
<ref bean="utilServices#rest"/>
|
||||||
|
<ref bean="passwordService#rest"/>
|
||||||
|
<ref bean="v2.groupService#rest"/>
|
||||||
|
</jaxrs:serviceBeans>
|
||||||
|
|
||||||
|
<jaxrs:providers>
|
||||||
|
<ref bean="jsonProvider"/>
|
||||||
|
<ref bean="xmlProvider"/>
|
||||||
|
<ref bean="authenticationInterceptor#rest"/>
|
||||||
|
<ref bean="permissionInterceptor#rest"/>
|
||||||
|
<ref bean="redbackServiceExceptionMapper"/>
|
||||||
|
<ref bean="passwordRuleViolationExceptionMapper"/>
|
||||||
|
<ref bean="requestValidationInterceptor#rest" />
|
||||||
|
<ref bean="threadLocalUserCleaner#rest"/>
|
||||||
|
</jaxrs:providers>
|
||||||
|
</jaxrs:server>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
|
@ -0,0 +1,273 @@
|
||||||
|
package org.apache.archiva.redback.rest.services.v2;
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
|
||||||
|
import org.apache.archiva.components.apacheds.ApacheDs;
|
||||||
|
import org.apache.archiva.redback.rest.api.model.GroupMapping;
|
||||||
|
import org.apache.archiva.redback.rest.api.services.v2.GroupService;
|
||||||
|
import org.apache.archiva.redback.rest.services.AbstractRestServicesTest;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
|
||||||
|
import org.apache.cxf.jaxrs.client.WebClient;
|
||||||
|
import org.assertj.core.api.Condition;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.naming.directory.Attributes;
|
||||||
|
import javax.naming.directory.BasicAttribute;
|
||||||
|
import javax.naming.directory.BasicAttributes;
|
||||||
|
import javax.naming.directory.DirContext;
|
||||||
|
import javax.naming.directory.InitialDirContext;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Olivier Lamy
|
||||||
|
*/
|
||||||
|
@RunWith( SpringJUnit4ClassRunner.class )
|
||||||
|
@ContextConfiguration(
|
||||||
|
locations = { "classpath:/ldap-spring-test.xml" } )
|
||||||
|
@DirtiesContext( classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD )
|
||||||
|
public class GroupServiceTest
|
||||||
|
extends AbstractRestServicesTest
|
||||||
|
{
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Named( value = "apacheDS#test" )
|
||||||
|
private ApacheDs apacheDs;
|
||||||
|
|
||||||
|
List<String> groups =
|
||||||
|
Arrays.asList( "Archiva System Administrator", "Internal Repo Manager", "Internal Repo Observer" );
|
||||||
|
|
||||||
|
private String suffix;
|
||||||
|
|
||||||
|
private String groupSuffix;
|
||||||
|
|
||||||
|
protected GroupService getGroupService( String authzHeader )
|
||||||
|
{
|
||||||
|
GroupService service =
|
||||||
|
JAXRSClientFactory.create( "http://localhost:" + getServerPort() + "/" + getRestServicesPath() + "/redback/v2/",
|
||||||
|
GroupService.class,
|
||||||
|
Collections.singletonList( new JacksonJaxbJsonProvider() ) );
|
||||||
|
|
||||||
|
// for debuging purpose
|
||||||
|
WebClient.getConfig( service ).getHttpConduit().getClient().setReceiveTimeout( getTimeout() );
|
||||||
|
|
||||||
|
if ( authzHeader != null )
|
||||||
|
{
|
||||||
|
WebClient.client( service ).header( "Authorization", authzHeader );
|
||||||
|
}
|
||||||
|
WebClient.client(service).header("Referer","http://localhost:"+getServerPort());
|
||||||
|
|
||||||
|
WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
|
||||||
|
WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );
|
||||||
|
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getSpringConfigLocation()
|
||||||
|
{
|
||||||
|
return "classpath*:spring-context.xml,classpath*:META-INF/spring-context.xml,classpath:/ldap-spring-test.xml";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startServer()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
super.startServer();
|
||||||
|
|
||||||
|
groupSuffix = apacheDs.addSimplePartition( "test", new String[]{ "archiva", "apache", "org" } ).getSuffix();
|
||||||
|
|
||||||
|
log.info( "groupSuffix: {}", groupSuffix );
|
||||||
|
|
||||||
|
suffix = "ou=People,dc=archiva,dc=apache,dc=org";
|
||||||
|
|
||||||
|
log.info( "DN Suffix: {}", suffix );
|
||||||
|
|
||||||
|
apacheDs.startServer();
|
||||||
|
|
||||||
|
BasicAttribute objectClass = new BasicAttribute( "objectClass" );
|
||||||
|
objectClass.add( "top" );
|
||||||
|
objectClass.add( "organizationalUnit" );
|
||||||
|
|
||||||
|
Attributes attributes = new BasicAttributes( true );
|
||||||
|
attributes.put( objectClass );
|
||||||
|
attributes.put( "organizationalUnitName", "foo" );
|
||||||
|
|
||||||
|
apacheDs.getAdminContext().createSubcontext( suffix, attributes );
|
||||||
|
|
||||||
|
createGroups();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopServer()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
// cleanup ldap entries
|
||||||
|
InitialDirContext context = apacheDs.getAdminContext();
|
||||||
|
|
||||||
|
for ( String group : this.groups )
|
||||||
|
{
|
||||||
|
context.unbind( createGroupDn( group ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
context.unbind( suffix );
|
||||||
|
|
||||||
|
context.close();
|
||||||
|
|
||||||
|
apacheDs.stopServer();
|
||||||
|
|
||||||
|
super.stopServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createGroups()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
InitialDirContext context = apacheDs.getAdminContext();
|
||||||
|
|
||||||
|
for ( String group : groups )
|
||||||
|
{
|
||||||
|
createGroup( context, group, createGroupDn( group ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createGroup( DirContext context, String groupName, String dn )
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
Attributes attributes = new BasicAttributes( true );
|
||||||
|
BasicAttribute objectClass = new BasicAttribute( "objectClass" );
|
||||||
|
objectClass.add( "top" );
|
||||||
|
objectClass.add( "groupOfUniqueNames" );
|
||||||
|
attributes.put( objectClass );
|
||||||
|
attributes.put( "cn", groupName );
|
||||||
|
BasicAttribute basicAttribute = new BasicAttribute( "uniquemember" );
|
||||||
|
|
||||||
|
basicAttribute.add( "uid=admin," + suffix );
|
||||||
|
|
||||||
|
attributes.put( basicAttribute );
|
||||||
|
context.createSubcontext( dn, attributes );
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createGroupDn( String cn )
|
||||||
|
{
|
||||||
|
return "cn=" + cn + "," + groupSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getAllGroups()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GroupService service = getGroupService( authorizationHeader );
|
||||||
|
|
||||||
|
List<String> allGroups = service.getGroups( Long.valueOf( 0 ), Long.valueOf( Long.MAX_VALUE ) ).stream( ).map( group -> group.getName( ) ).collect( Collectors.toList( ) );
|
||||||
|
|
||||||
|
assertThat( allGroups ).isNotNull().isNotEmpty().hasSize( 3 ).containsAll( groups );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
log.error( e.getMessage(), e );
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getGroupMappings()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GroupService service = getGroupService( authorizationHeader );
|
||||||
|
|
||||||
|
List<GroupMapping> mappings = service.getGroupMappings();
|
||||||
|
|
||||||
|
assertThat( mappings ).isNotNull().isNotEmpty().hasSize( 3 );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
log.error( e.getMessage(), e );
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addThenRemove()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GroupService service = getGroupService( authorizationHeader );
|
||||||
|
|
||||||
|
List<GroupMapping> mappings = service.getGroupMappings();
|
||||||
|
|
||||||
|
assertThat( mappings ).isNotNull().isNotEmpty().hasSize( 3 );
|
||||||
|
|
||||||
|
GroupMapping groupMapping = new GroupMapping( "ldap group", Arrays.asList( "redback role" ) );
|
||||||
|
|
||||||
|
service.addGroupMapping( groupMapping );
|
||||||
|
|
||||||
|
mappings = service.getGroupMappings();
|
||||||
|
|
||||||
|
assertThat( mappings ).isNotNull().isNotEmpty().hasSize( 4 ).are(
|
||||||
|
new Condition<GroupMapping>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public boolean matches( GroupMapping mapping )
|
||||||
|
{
|
||||||
|
if ( StringUtils.equals( "ldap group", mapping.getGroup() ) )
|
||||||
|
{
|
||||||
|
assertThat( mapping.getRoleNames() ).isNotNull().isNotEmpty().containsOnly(
|
||||||
|
"redback role" );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
service.removeGroupMapping( "ldap group" );
|
||||||
|
|
||||||
|
mappings = service.getGroupMappings();
|
||||||
|
|
||||||
|
assertThat( mappings ).isNotNull().isNotEmpty().hasSize( 3 );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
log.error( e.getMessage(), e );
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -204,7 +204,7 @@ public class DefaultLdapController
|
||||||
{
|
{
|
||||||
SearchResult result = results.nextElement();
|
SearchResult result = results.nextElement();
|
||||||
|
|
||||||
users.add( mapper.getUser( result.getAttributes() ) );
|
users.add( mapper.getUser( result.getNameInNamespace(), result.getAttributes() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return users;
|
return users;
|
||||||
|
@ -247,7 +247,7 @@ public class DefaultLdapController
|
||||||
{
|
{
|
||||||
SearchResult result = results.nextElement();
|
SearchResult result = results.nextElement();
|
||||||
|
|
||||||
users.add( mapper.getUser( result.getAttributes() ) );
|
users.add( mapper.getUser( result.getNameInNamespace(), result.getAttributes() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return users;
|
return users;
|
||||||
|
@ -360,7 +360,7 @@ public class DefaultLdapController
|
||||||
|
|
||||||
log.info( "Found user: {}", username );
|
log.info( "Found user: {}", username );
|
||||||
|
|
||||||
return mapper.getUser( next.getAttributes() );
|
return mapper.getUser( next.getNameInNamespace(), next.getAttributes() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue