Java tutorial
/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.xwiki.contrib.oidc.provider.internal.store; import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; import javax.inject.Singleton; import org.apache.commons.lang3.StringUtils; import org.xwiki.component.annotation.Component; import org.xwiki.model.reference.DocumentReference; import org.xwiki.model.reference.DocumentReferenceResolver; import org.xwiki.query.Query; import org.xwiki.query.QueryException; import org.xwiki.query.QueryManager; import com.nimbusds.oauth2.sdk.AuthorizationCode; import com.nimbusds.oauth2.sdk.id.ClientID; import com.nimbusds.oauth2.sdk.token.AccessToken; import com.xpn.xwiki.XWikiContext; import com.xpn.xwiki.XWikiException; import com.xpn.xwiki.doc.XWikiDocument; import com.xpn.xwiki.objects.BaseObject; @Component(roles = OIDCStore.class) @Singleton public class OIDCStore { @Inject private Provider<XWikiContext> xcontextProvider; @Inject private QueryManager queryManager; @Inject @Named("current") private DocumentReferenceResolver<String> resolver; private Map<AuthorizationCode, DocumentReference> authorizationMap = new ConcurrentHashMap<>(); public OIDCConsent getConsent(DocumentReference userReference, ClientID clientID, URI redirectURI) throws XWikiException { XWikiContext xcontext = this.xcontextProvider.get(); XWikiDocument userDocument = xcontext.getWiki().getDocument(userReference, xcontext); for (OIDCConsent consent : (List<OIDCConsent>) (List) userDocument.getXObjects(OIDCConsent.REFERENCE)) { if (consent != null) { if (clientID.equals(consent.getClientID()) && (redirectURI == null || redirectURI.equals(consent.getRedirectURI()))) { return consent; } } } return null; } public OIDCConsent getConsent(Map<String, String> entries) throws QueryException, XWikiException { StringBuilder builder = new StringBuilder(); for (String key : entries.keySet()) { if (builder.length() == 0) { builder.append("select doc.fullName, consent.number from Document doc, doc.object(" + OIDCConsent.REFERENCE_STRING + ") as consent where "); } else { builder.append(" AND "); } builder.append("consent." + key + " = :" + key); } Query query = this.queryManager.createQuery(builder.toString(), Query.XWQL); for (Map.Entry<String, String> entry : entries.entrySet()) { query.bindValue(entry.getKey(), entry.getValue()); } List<Object[]> users = query.execute(); if (users.isEmpty()) { return null; } // TODO: return an error when there is several ? Object[] user = users.get(0); XWikiContext xcontext = this.xcontextProvider.get(); DocumentReference userReference = this.resolver.resolve((String) user[0]); XWikiDocument userDocument = xcontext.getWiki().getDocument(userReference, xcontext); return (OIDCConsent) userDocument.getXObject(OIDCConsent.REFERENCE, ((Number) user[1]).intValue()); } public OIDCConsent getConsent(AccessToken accessToken) throws QueryException, XWikiException { Map<String, String> entries = new HashMap<>(); entries.put(OIDCConsent.FIELD_ACCESSTOKEN, accessToken.getValue()); return getConsent(entries); } public OIDCConsent getConsent(ClientID clientID, URI redirectURI) throws QueryException, XWikiException { Map<String, String> entries = new HashMap<>(); entries.put(OIDCConsent.FIELD_CLIENTID, clientID.getValue()); entries.put(OIDCConsent.FIELD_REDIRECTURI, redirectURI.toString()); return getConsent(entries); } public OIDCConsent getConsent(ClientID clientID, URI redirectURI, AuthorizationCode code) throws XWikiException { DocumentReference userReference = getUserReference(code); if (userReference == null) { return null; } XWikiContext xcontext = this.xcontextProvider.get(); XWikiDocument userDocument = xcontext.getWiki().getDocument(userReference, xcontext); if (userDocument.isNew()) { return null; } String clientIDString = clientID.getValue(); String redirectURIString = redirectURI.toString(); for (BaseObject consent : userDocument.getXObjects(OIDCConsent.REFERENCE)) { if (consent != null && clientIDString.equals(consent.getStringValue(OIDCConsent.FIELD_CLIENTID)) && redirectURIString.equals(consent.getStringValue(OIDCConsent.FIELD_REDIRECTURI))) { return (OIDCConsent) consent; } } return null; } public XWikiDocument getUserDocument() throws XWikiException { XWikiContext xcontext = this.xcontextProvider.get(); return xcontext.getWiki().getDocument(xcontext.getUserReference(), xcontext); } public OIDCConsent saveConsent(OIDCConsent consent, String comment) throws XWikiException { XWikiDocument userDocument = consent.getOwnerDocument(); XWikiContext xcontext = this.xcontextProvider.get(); xcontext.getWiki().saveDocument(userDocument, comment, xcontext); return consent; } public BaseObject getUserObject(OIDCConsent consent) throws XWikiException { XWikiContext xcontext = this.xcontextProvider.get(); XWikiDocument userDocument = consent.getOwnerDocument(); return userDocument.getXObject(xcontext.getWiki().getUserClass(xcontext).getDocumentReference()); } public URI getUserAvatarURI(XWikiDocument userDocument) throws URISyntaxException { String avatar = userDocument.getStringValue("avatar"); return StringUtils.isEmpty(avatar) ? null : new URI(userDocument.getExternalAttachmentURL(avatar, "download", this.xcontextProvider.get())); } public URI getUserProfileURI(XWikiDocument userDocument) throws URISyntaxException { return new URI(userDocument.getExternalURL("view", this.xcontextProvider.get())); } public DocumentReference getUserReference(AuthorizationCode code) { return this.authorizationMap.get(code); } public void setAuthorizationCode(AuthorizationCode code, DocumentReference userReference) { this.authorizationMap.put(code, userReference); } public void removeAuthorizationCode(AuthorizationCode code) { this.authorizationMap.remove(code); } }