true
if the session is allowed to play the file,
28 | * false
otherwise.
29 | * @throws MalformedURLException if the URL to the validation server is malformed.
30 | * @throws IOException if something went wrong when connecting to the server.
31 | * @throws MCMOutputException if the output from MCM cannot be read.
32 | */
33 | public abstract boolean validateRightsToPlayFile(String sessionID,
34 | String objectID, String filename) throws MalformedURLException,
35 | IOException, MCMOutputException;
36 |
37 | }
--------------------------------------------------------------------------------
/wowza-mcm-authorization-module/src/test/java/dk/statsbiblioteket/medieplatform/wowza/plugin/authentication/model/MCMOReturnValueWrapperTest.java:
--------------------------------------------------------------------------------
1 | package dk.statsbiblioteket.medieplatform.wowza.plugin.authentication.model;
2 |
3 | import com.wowza.wms.logging.WMSLoggerFactory;
4 | import org.apache.log4j.Logger;
5 | import org.junit.jupiter.api.AfterEach;
6 | import org.junit.jupiter.api.BeforeEach;
7 | import org.junit.jupiter.api.Test;
8 | import static org.junit.jupiter.api.Assertions.*;
9 |
10 | import java.io.FileInputStream;
11 | import java.io.FileNotFoundException;
12 | import java.io.InputStream;
13 | import java.util.List;
14 |
15 |
16 | /**
17 | * Tests for parsing XML results in the return value wrapper.
18 | */
19 | public class MCMOReturnValueWrapperTest {
20 |
21 | private String filenameOfvalidMCMOutputFull = getClass().getClassLoader().getResource(
22 | "test_data_MCM_output_full.xml").getPath();
23 | private String filenameOfvalidMCMOutputMultipleFiles = getClass().getClassLoader().getResource(
24 | "test_data_MCM_output_multiple_files.xml").getPath();
25 | private String filenameOfvalidMCMOutputInvalidSession = getClass().getClassLoader().getResource(
26 | "test_data_MCM_output_invalid_session.xml").getPath();
27 | private String filenameOfInvalidMCMOutput = getClass().getClassLoader().getResource(
28 | "test_data_invalid_output.xml").getPath();
29 |
30 | private Logger logger;
31 |
32 | public MCMOReturnValueWrapperTest() {
33 | super();
34 | this.logger = WMSLoggerFactory.getLogger(this.getClass());
35 | }
36 |
37 | @BeforeEach
38 | public void setUp() throws Exception {
39 | org.apache.log4j.BasicConfigurator.configure();
40 | }
41 |
42 | @AfterEach
43 | public void tearDown() throws Exception {
44 | org.apache.log4j.BasicConfigurator.resetConfiguration();
45 | }
46 |
47 | @Test
48 | public void testExtractOutputFilename() throws FileNotFoundException, MCMOutputException {
49 | InputStream is = getTestDataFileAsInputStream(filenameOfvalidMCMOutputFull);
50 | MCMOReturnValueWrapper returnWrapper = new MCMOReturnValueWrapper(logger, is);
51 | String returnedValue = returnWrapper.getFilenames().get(0);
52 | String expectedValue = "P1_0000_0200_910201_001.mp3";
53 | assertEquals(expectedValue, returnedValue, "Filename");
54 | }
55 |
56 | @Test
57 | public void testExtractOutputObjectID() throws FileNotFoundException, MCMOutputException {
58 | InputStream is = getTestDataFileAsInputStream(filenameOfvalidMCMOutputFull);
59 | MCMOReturnValueWrapper returnWrapper = new MCMOReturnValueWrapper(logger, is);
60 | String returnedValue = returnWrapper.getObjectID();
61 | String expectedValue = "643703";
62 | assertEquals(expectedValue, returnedValue, "ObjectID");
63 | }
64 |
65 | @Test
66 | public void testExtractOutputInvalidSessionID() throws FileNotFoundException, MCMOutputException {
67 | InputStream is = getTestDataFileAsInputStream(filenameOfvalidMCMOutputInvalidSession);
68 | MCMOReturnValueWrapper returnWrapper = new MCMOReturnValueWrapper(logger, is);
69 | boolean returnedValue = returnWrapper.isSessionValid();
70 | boolean expectedValue = false;
71 | assertEquals(expectedValue, returnedValue, "Valid session");
72 | }
73 |
74 | @Test
75 | public void testExtractOutputBogusXML() throws FileNotFoundException, MCMOutputException {
76 | InputStream is = getTestDataFileAsInputStream(filenameOfInvalidMCMOutput);
77 | assertThrows(MCMOutputException.class, () -> {
78 | new MCMOReturnValueWrapper(logger, is);
79 | });
80 |
81 | }
82 |
83 | @Test
84 | public void testExtractMultipleFilenames() throws FileNotFoundException, MCMOutputException {
85 | InputStream is = getTestDataFileAsInputStream(filenameOfvalidMCMOutputMultipleFiles);
86 | MCMOReturnValueWrapper returnWrapper = new MCMOReturnValueWrapper(logger, is);
87 | List
48 | * Extracts streamname, query string and client ip from the http session
49 | *
50 | * @param httpSession The http session
51 | * @return true if allowed, false otherwise.
52 | * @see #checkTicket(java.lang.String, java.lang.String, java.lang.String)
53 | */
54 | public boolean checkTicket(IHTTPStreamerSession httpSession) {
55 | return checkTicket(httpSession.getStreamName(), httpSession.getQueryStr(), getClientIp(httpSession));
56 | }
57 |
58 | private boolean checkTicket(String name, String query, String ip) {
59 | logger.trace(
60 | "checkTicket(String name=" + name
61 | + ", String query=" + query + ")");
62 | try {
63 | Ticket streamingTicket = StringAndTextUtil.getTicket(query, ticketTool);
64 | logger.debug("Ticket received: " + (streamingTicket != null ? streamingTicket.getId() : "null"));
65 | if (
66 | streamingTicket != null &&
67 | isClientAllowed(streamingTicket, ip) &&
68 | ticketForThisPresentationType(streamingTicket) &&
69 | doesTicketAllowThisStream(name, streamingTicket)
70 | ) {
71 | logger.info(
72 | "checkTicket(String name=" + name
73 | + ", String query=" + query + ") successful.");
74 | return true;
75 | } else {
76 | logger.info("Client not allowed to get content streamed for String name=" + name
77 | + ", String query=" + query
78 | + ")");
79 | return false;
80 | }
81 | } catch (IllegallyFormattedQueryStringException e) {
82 | logger.warn("Illegally formatted query string [" + query + "].");
83 | return false;
84 | }
85 | }
86 |
87 | private boolean ticketForThisPresentationType(Ticket streamingTicket) {
88 | return streamingTicket.getType().equals(presentationType);
89 | }
90 |
91 | private boolean doesTicketAllowThisStream(String name, Ticket streamingTicket) {
92 | name = clean(name);
93 | for (String resource : streamingTicket.getResources()) {
94 | if (resource.contains(name)){
95 | return true;
96 | }
97 | }
98 | return false;
99 | }
100 |
101 | /**
102 | * This method checks if the ticket is given to the same IP address as the client
103 | * @param streamingTicket the ticket
104 | * @param ip ip of client
105 | * @return true if the ip is the same for the ticket and the user
106 | */
107 | private boolean isClientAllowed(Ticket streamingTicket, String ip) {
108 |
109 | boolean isAllowed = (ip != null) && (ip.equals(streamingTicket.getIpAddress()));
110 | logger.debug("isClientAllowed - ipOfClient: " + ip + ", streamingTicket.getIpAddress(): "
111 | + streamingTicket.getIpAddress() + ", isAllowed: " + isAllowed);
112 | return isAllowed;
113 | }
114 |
115 | private String clean(String name) {
116 | if (name.contains(".")){
117 | name = name.substring(0, name.indexOf("."));
118 | }
119 | if (name.contains(":")) {
120 | name = name.substring(name.lastIndexOf(':') + 1);
121 | }
122 |
123 | return name;
124 | }
125 |
126 | private String getClientIp(IClient client) {
127 | String IP = (client.getForwardedIP()) != null ? client.getForwardedIP() : client.getIp();
128 | return IP;
129 | }
130 |
131 | private String getClientIp(IHTTPStreamerSession httpSession) {
132 | String IP = (httpSession.getForwardedIP()) != null ? httpSession.getForwardedIP() : httpSession.getIpAddress();
133 | return IP;
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/wowza-ticket-checker-module/src/main/java/dk/statsbiblioteket/medieplatform/wowza/plugin/ticket/TicketTool.java:
--------------------------------------------------------------------------------
1 | package dk.statsbiblioteket.medieplatform.wowza.plugin.ticket;
2 |
3 | import java.util.Arrays;
4 |
5 | import javax.ws.rs.WebApplicationException;
6 | import javax.ws.rs.core.Response.StatusType;
7 |
8 | import org.apache.cxf.jaxrs.client.WebClient;
9 |
10 | import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
11 | import com.wowza.wms.logging.WMSLogger;
12 |
13 | import dk.statsbiblioteket.medieplatform.ticketsystem.Ticket;
14 |
15 | public class TicketTool implements TicketToolInterface {
16 |
17 | private WMSLogger logger;
18 | private final String serviceUrl;
19 |
20 | public TicketTool(String serviceURL, WMSLogger logger) {
21 | super();
22 | this.serviceUrl = serviceURL;
23 | this.logger = logger;
24 | }
25 |
26 | /* (non-Javadoc)
27 | * @see dk.statsbiblioteket.medieplatform.wowza.plugin.ticket.TicketToolInterface#resolveTicket(java.lang.String)
28 | */
29 | @Override
30 | public Ticket resolveTicket(String ticketID) {
31 | WebClient client = getWebclient();
32 | try {
33 | Ticket ticketXml = client.path("/resolveTicket/").path(ticketID).get(Ticket.class);
34 | logger.debug("resolveTicket: Ticket received: '" + ticketID + "'");
35 | return ticketXml;
36 |
37 | } catch (WebApplicationException e) {
38 | StatusType responseStatus = e.getResponse().getStatusInfo();
39 | logger.debug("The session might have timed out for ticket '"
40 | + ticketID + "'. Ticket service response status: " + responseStatus.getStatusCode());
41 | return null;
42 | } finally {
43 | client.close();
44 | }
45 | }
46 |
47 | private WebClient getWebclient() {
48 | WebClient client = WebClient.create(serviceUrl, Arrays.asList(new JacksonJaxbJsonProvider()));
49 | return client;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/wowza-ticket-checker-module/src/test/java/dk/statsbiblioteket/medieplatform/wowza/plugin/TicketCheckerTest.java:
--------------------------------------------------------------------------------
1 | package dk.statsbiblioteket.medieplatform.wowza.plugin;
2 |
3 | import com.wowza.wms.application.IApplicationInstance;
4 | import com.wowza.wms.client.IClient;
5 | import com.wowza.wms.logging.WMSLoggerFactory;
6 | import com.wowza.wms.stream.IMediaStream;
7 | import org.apache.log4j.Logger;
8 | import org.junit.jupiter.api.AfterEach;
9 | import org.junit.jupiter.api.BeforeEach;
10 | import org.junit.jupiter.api.Test;
11 | import static org.junit.jupiter.api.Assertions.*;
12 | import org.mockito.invocation.InvocationOnMock;
13 |
14 | import dk.statsbiblioteket.medieplatform.ticketsystem.Property;
15 | import dk.statsbiblioteket.medieplatform.ticketsystem.Ticket;
16 | import dk.statsbiblioteket.medieplatform.wowza.plugin.ticket.TicketToolInterface;
17 |
18 | import static org.mockito.Mockito.mock;
19 | import static org.mockito.Mockito.when;
20 | import static org.mockito.ArgumentMatchers.*;
21 |
22 | import java.util.ArrayList;
23 | import java.util.Arrays;
24 | import java.util.HashMap;
25 | import java.util.List;
26 | import java.util.Map;
27 |
28 |
29 | public class TicketCheckerTest {
30 |
31 | public static final String QUERY_STRING = "ticket=";
32 | private Logger logger;
33 |
34 | TicketToolInterface ticketTool;
35 |
36 | IApplicationInstance iAppInstance = mock(IApplicationInstance.class);
37 |
38 | String goodIP = "127.0.0.1";
39 | String badIP = "127.0.0.2-Invalid-ip";
40 | String programID = "0ef8f946-4e90-4c9d-843a-a03504d2ee6c";
41 |
42 | String name = "0ef8f946-4e90-4c9d-843a-a03504d2ee6c.flv";
43 |
44 |
45 | public TicketCheckerTest() {
46 | super();
47 | this.logger = WMSLoggerFactory.getLogger(this.getClass());
48 | }
49 |
50 | @BeforeEach
51 | public void setUp() throws Exception {
52 | org.apache.log4j.BasicConfigurator.configure();
53 | ticketTool = mock(TicketToolInterface.class);
54 | }
55 |
56 | @AfterEach
57 | public void tearDown() throws Exception {
58 | org.apache.log4j.BasicConfigurator.resetConfiguration();
59 | }
60 |
61 | @Test
62 | public void testUserNotAllowedToPlayFile() {
63 | // Setup environment
64 | Map