Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Add functionality to capture user events in the database and… #6913

Merged
merged 3 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.orcid.core.common.manager;

import org.orcid.core.utils.EventType;
import org.orcid.pojo.ajaxForm.RequestInfoForm;

import javax.servlet.http.HttpServletRequest;

/**
*
* @author Daniel Palafox
*
*/
public interface EventManager {

boolean removeEvents(String orcid);

void createEvent(String orcid, EventType eventType, HttpServletRequest request, RequestInfoForm requestInfoForm);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package org.orcid.core.common.manager.impl;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.orcid.core.common.manager.EventManager;
import org.orcid.core.constants.OrcidOauth2Constants;
import org.orcid.core.manager.ClientDetailsEntityCacheManager;
import org.orcid.core.utils.EventType;
import org.orcid.persistence.dao.EventDao;
import org.orcid.persistence.jpa.entities.ClientDetailsEntity;
import org.orcid.persistence.jpa.entities.EventEntity;
import org.orcid.pojo.ajaxForm.RequestInfoForm;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

/**
*
* @author Daniel Palafox
*
*/
public class EventManagerImpl implements EventManager {

@Resource
private EventDao eventDao;

@Resource
private ClientDetailsEntityCacheManager clientDetailsEntityCacheManager;

@Override
public boolean removeEvents(String orcid) {
return eventDao.removeEvents(orcid);
}

@Override
public void createEvent(String orcid, EventType eventType, HttpServletRequest request, RequestInfoForm requestInfoForm) {
String label = "Website";
String clientId = null;
String redirectUrl = null;
String publicPage = null;

switch (eventType) {
case PUBLIC_PAGE:
publicPage = orcid;
orcid = null;
break;
case REAUTHORIZE:
clientId = requestInfoForm.getClientId();
redirectUrl = requestInfoForm.getRedirectUrl();
label = "OAuth " + requestInfoForm.getClientName();
break;
default:
if (request != null) {
Boolean isOauth2ScreensRequest = (Boolean) request.getSession().getAttribute(OrcidOauth2Constants.OAUTH_2SCREENS);
if (isOauth2ScreensRequest != null && isOauth2ScreensRequest) {
String queryString = (String) request.getSession().getAttribute(OrcidOauth2Constants.OAUTH_QUERY_STRING);
clientId = getParameterValue(queryString, "client_id");
redirectUrl = getParameterValue(queryString, "redirect_uri");
ClientDetailsEntity clientDetailsEntity = clientDetailsEntityCacheManager.retrieve(clientId);
label = "OAuth " + clientDetailsEntity.getClientName();
}
}
}

EventEntity eventEntity = new EventEntity();

eventEntity.setOrcid(orcid);
eventEntity.setEventType(eventType.getValue());
eventEntity.setClientId(clientId);
eventEntity.setRedirectUrl(redirectUrl);
eventEntity.setLabel(label);
eventEntity.setPublicPage(publicPage);

eventDao.createEvent(eventEntity);
}

private String getParameterValue(String queryString, String parameter) {
if (StringUtils.isNotEmpty(queryString)) {
try {
queryString = URLDecoder.decode(queryString, StandardCharsets.UTF_8.toString());
} catch (UnsupportedEncodingException u) {
// l
}
String[] parameters = queryString.split("&");
for (String p : parameters) {
String[] keyValuePair = p.split("=");
if (parameter.equals(keyValuePair[0])) {
return keyValuePair[1];
}
}
}
return null;
}
}
3 changes: 3 additions & 0 deletions orcid-core/src/main/java/org/orcid/core/togglz/Features.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import org.togglz.core.context.FeatureContext;

public enum Features implements Feature {
@Label("Track user events")
EVENTS,

@Label("Source sorting")
SOURCE_SORTING,

Expand Down
20 changes: 20 additions & 0 deletions orcid-core/src/main/java/org/orcid/core/utils/EventType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.orcid.core.utils;

public enum EventType {
SIGN_IN("Sign-In"),
NEW_REGISTRATION("New-Registration"),
AUTHORIZE("Authorize"),
AUTHORIZE_DENY("Authorize-Deny"),
REAUTHORIZE("Reauthorize"),
PUBLIC_PAGE("Public-Page");

private final String value;

EventType(String v) {
value = v;
}

public String getValue() {
return value;
}
}
2 changes: 2 additions & 0 deletions orcid-core/src/main/resources/orcid-core-context.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,8 @@
<constructor-arg index="4" value="${org.orcid.core.utils.cache.redis.connection_timeout_millis:10000}" />
</bean>

<bean id="eventManager" class="org.orcid.core.common.manager.impl.EventManagerImpl"/>

<bean id="emailDomainManager" class="org.orcid.core.common.manager.impl.EmailDomainManagerImpl"/>

</beans>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.orcid.persistence.dao;

import org.orcid.persistence.jpa.entities.EventEntity;

import java.util.List;

/**
*
* @author Daniel Palafox
*
*/
public interface EventDao extends GenericDao<EventEntity, Long>{

boolean removeEvents(String orcid);

List<EventEntity> getEvents(String orcid);

void createEvent(EventEntity eventEntity);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.orcid.persistence.dao.impl;

import org.orcid.persistence.aop.UpdateProfileLastModified;
import org.orcid.persistence.dao.EventDao;
import org.orcid.persistence.jpa.entities.EmailEntity;
import org.orcid.persistence.jpa.entities.EventEntity;
import org.orcid.persistence.jpa.entities.SpamEntity;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Query;
import javax.persistence.TypedQuery;
import java.util.List;

/**
* @author Daniel Palafox
*/
public class EventDaoImpl extends GenericDaoImpl<EventEntity, Long> implements EventDao {

public EventDaoImpl() {
super(EventEntity.class);
}

@Override
public List<EventEntity> getEvents(String orcid) {
TypedQuery<EventEntity> query = entityManager.createQuery("from EventEntity where orcid=:orcid", EventEntity.class);
query.setParameter("orcid", orcid);
List<EventEntity> results = query.getResultList();
return results.isEmpty() ? null : results;
}

@Override
@Transactional
public void createEvent(EventEntity eventEntity) {
entityManager.persist(eventEntity);
}

@Override
@Transactional
public boolean removeEvents(String orcid) {
Query query = entityManager.createQuery("delete from EventEntity where orcid = :orcid");
query.setParameter("orcid", orcid);
query.executeUpdate();
return query.executeUpdate() > 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.orcid.persistence.jpa.entities;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

/**
*
* @author Daniel Palafox
*
*/
@Entity
@Table(name = "event")
public class EventEntity extends BaseEntity<Long> implements OrcidAware {
private static final long serialVersionUID = 1L;
private Long id;
private String orcid;
private String eventType;
private String clientId;
private String redirectUrl;
private String label;
private String publicPage;

@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO, generator = "event_seq")
@SequenceGenerator(name = "event_seq", sequenceName = "event_seq", allocationSize = 1)
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

@Column(name = "orcid")
public String getOrcid() {
return orcid;
}

public void setOrcid(String orcid) {
this.orcid = orcid;
}

@Column(name = "event_type")
public String getEventType() { return eventType; }

public void setEventType(String eventType) { this.eventType = eventType; }

@Column(name = "client_id")
public String getClientId() { return clientId; }

public void setClientId(String client_id) { this.clientId = client_id; }

@Column(name = "redirect_url")
public String getRedirectUrl() { return redirectUrl; }

public void setRedirectUrl(String redirect_url) { this.redirectUrl = redirect_url; }

@Column(name = "label")
public String getLabel() { return label; }

public void setLabel(String label) { this.label = label; }

@Column(name = "public_page")
public String getPublicPage() { return publicPage; }

public void setPublicPage(String public_page) { this.publicPage = public_page; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
<class>org.orcid.persistence.jpa.entities.ResearchResourceItemEntity</class>
<class>org.orcid.persistence.jpa.entities.FindMyStuffHistoryEntity</class>
<class>org.orcid.persistence.jpa.entities.SpamEntity</class>
<class>org.orcid.persistence.jpa.entities.EventEntity</class>
<class>org.orcid.persistence.jpa.entities.EmailDomainEntity</class>

<!-- OAuth entities -->
Expand Down Expand Up @@ -105,4 +106,4 @@

</persistence-unit>

</persistence>
</persistence>
4 changes: 3 additions & 1 deletion orcid-persistence/src/main/resources/db-master.xml
Original file line number Diff line number Diff line change
Expand Up @@ -374,4 +374,6 @@
<include file="/db/updates/identifier-types/update-ethos-to-be-case-sensitive.xml" />
<include file="/db/updates/dw_client_details_add_user_obo_enabled.xml" />
<include file="/db/updates/create_email_domain_mapping_tables.xml" />
</databaseChangeLog>
<include file="/db/updates/create_event_table.xml" />
<include file="/db/updates/dw_event.xml" />
</databaseChangeLog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">

<changeSet id="CREATE-EVENT-TABLE" author="Daniel Palafox">
<createTable tableName="event">
<column name="id" type="bigint">
<constraints nullable="false" primaryKey="true"
primaryKeyName="event_pkey"/>
</column>
<column name="orcid" type="VARCHAR(19)"/>
<column name="event_type" type="VARCHAR(20)"/>
<column name="client_id" type="VARCHAR(255)"/>
<column name="redirect_url" type="VARCHAR(255)"/>
<column name="label" type="VARCHAR(255)"/>
<column name="public_page" type="VARCHAR(19)"/>
<column name="date_created" type="TIMESTAMP WITH TIME ZONE"/>
<column name="last_modified" type="TIMESTAMP WITH TIME ZONE"/>
</createTable>

<addForeignKeyConstraint constraintName="event_orcid_fk" baseTableName="event"
baseColumnNames="orcid" referencedTableName="profile" referencedColumnNames="orcid"/>
</changeSet>

<changeSet id="CREATE-EVENT-SEQUENCES" author="Daniel Palafox">
<preConditions onFail="MARK_RAN">
<not>
<sequenceExists sequenceName="event_seq"/>
</not>
</preConditions>
<createSequence sequenceName="event_seq"/>
</changeSet>

<changeSet id="CREATE-EVENT-AUTOCOLS" author="Daniel Palafox" dbms="hsqldb">
<addAutoIncrement tableName="event" columnName="id" columnDataType="bigint"/>
</changeSet>

<changeSet id="GRANT-READ-PERMISSIONS-TO-ORCIDRO-ON-EVENT" author="Daniel Palafox" dbms="postgresql">
<preConditions>
<sqlCheck expectedResult="1">SELECT 1 FROM pg_roles WHERE rolname='orcidro'</sqlCheck>
</preConditions>
<sql>GRANT SELECT ON event to orcidro;</sql>
</changeSet>

</databaseChangeLog>
Loading