package io.fathom.cloud.identity.api.os.resources.extensions; import io.fathom.cloud.CloudException; import io.fathom.cloud.identity.api.os.resources.IdentityResourceBase; import io.fathom.cloud.identity.api.os.resources.RolesResource; import io.fathom.cloud.identity.services.IdentityService; import io.fathom.cloud.identity.services.IdentityService.UserCreationData; import io.fathom.cloud.openstack.client.identity.model.RegisterRequest; import io.fathom.cloud.openstack.client.identity.model.RegisterResponse; import io.fathom.cloud.protobuf.IdentityModel.DomainData; import io.fathom.cloud.protobuf.IdentityModel.UserData; import io.fathom.cloud.server.resources.ClientCertificate; import javax.inject.Inject; import javax.ws.rs.POST; import javax.ws.rs.Path; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Strings; import com.google.common.io.BaseEncoding; import com.google.protobuf.ByteString; @Path("/openstack/identity/extensions/register") public class RegisterResource extends IdentityResourceBase { private static final Logger log = LoggerFactory.getLogger(RolesResource.class); @Inject IdentityService identityService; @POST public RegisterResponse register(RegisterRequest request) throws CloudException { String email = request.email; if (Strings.isNullOrEmpty(email)) { throw new IllegalArgumentException(); } email = email.trim(); ClientCertificate clientCertificate = getClientCertificate(); if (clientCertificate == null) { throw new IllegalArgumentException("Client certificate not provided"); } if (request.challengeResponse == null || Strings.isNullOrEmpty(request.challengeResponse.response)) { ByteString challenge = loginService.createRegistrationChallenge(clientCertificate); RegisterResponse response = new RegisterResponse(); response.challenge = BaseEncoding.base64().encode(challenge.toByteArray()); return response; } DomainData domain = identityService.getDefaultDomain(); UserData.Builder b = UserData.newBuilder(); // We allow multiple systems to share an email address // so we use the public key hash as our unique id { ByteString publicKeySha1 = clientCertificate.getPublicKeySha1(); String hex = BaseEncoding.base16().encode(publicKeySha1.toByteArray()); b.setName("__pubkey__" + hex); } b.setDomainId(domain.getId()); b.setEnabled(true); b.setEmail(request.email); String password = null; UserCreationData userCreationData = new UserCreationData(domain, b, password); userCreationData.publicKeySha1 = clientCertificate.getPublicKeySha1(); userCreationData.publicKeyChallengeRequest = fromBase64(request.challengeResponse.challenge); userCreationData.publicKeyChallengeResponse = fromBase64(request.challengeResponse.response); UserData user = identityService.createUser(userCreationData); RegisterResponse response = new RegisterResponse(); response.userId = "" + user.getId(); return response; } private static ByteString fromBase64(String s) { return ByteString.copyFrom(BaseEncoding.base64().decode(s)); } }