IoTivity Cloud feature
[platform/upstream/iotivity.git] / cloud / interface / src / main / java / org / iotivity / cloud / ciserver / protocols / CoapAuthHandler.java
1 package org.iotivity.cloud.ciserver.protocols;
2
3 import java.net.InetSocketAddress;
4 import java.nio.charset.StandardCharsets;
5 import java.util.HashMap;
6 import java.util.Map;
7
8 import org.iotivity.cloud.base.CoapClient;
9 import org.iotivity.cloud.base.protocols.coap.CoapRequest;
10 import org.iotivity.cloud.base.protocols.coap.CoapResponse;
11 import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
12 import org.iotivity.cloud.ciserver.Constants;
13 import org.iotivity.cloud.util.Cbor;
14 import org.iotivity.cloud.util.JSONUtil;
15 import org.iotivity.cloud.util.Logger;
16
17 import io.netty.channel.ChannelDuplexHandler;
18 import io.netty.channel.ChannelHandler.Sharable;
19 import io.netty.channel.ChannelHandlerContext;
20 import io.netty.channel.SimpleChannelInboundHandler;
21 import io.netty.util.AttributeKey;
22
23 @Sharable
24 public class CoapAuthHandler extends ChannelDuplexHandler {
25
26     private static final AttributeKey<ChannelHandlerContext> keyAuthClient = AttributeKey
27             .newInstance("authCtx");
28
29     private class AccountHandler
30             extends SimpleChannelInboundHandler<CoapResponse> {
31
32         @Override
33         public void channelRead0(ChannelHandlerContext ctx, CoapResponse msg)
34                 throws Exception {
35             Logger.d("Receive response from account, forward to client");
36
37             ChannelHandlerContext ctxToDevice = ctx.channel()
38                     .attr(keyAuthClient).get();
39
40             if (msg.getResponseCode() == CoapStatus.CREATED) {
41                 Map<String, String> response = JSONUtil
42                         .parseJSON(new String(msg.getPayload(), StandardCharsets.UTF_8));
43
44                 String userId = response.get("userid");
45                 if (userId != null) {
46                     ctxToDevice.channel().attr(Constants.Attribute_UserId)
47                             .set(userId);
48                 }
49                 msg.setPayload(cbor.encodingPayloadToCbor(response));
50
51                 CoapAuthHandler authHandler = ctxToDevice.channel().pipeline()
52                         .get(CoapAuthHandler.class);
53
54                 ctxToDevice.channel().pipeline().remove(authHandler);
55             }
56
57             ctxToDevice.writeAndFlush(msg);
58
59             if (msg.getResponseCode() != CoapStatus.CREATED)
60                 ctxToDevice.close();
61         }
62
63         @Override
64         public void exceptionCaught(ChannelHandlerContext ctx,
65                 Throwable cause) {
66             cause.printStackTrace();
67             ctx.close();
68         }
69     }
70
71     private CoapClient accountClient = new CoapClient();
72
73     public CoapAuthHandler(String accountAddress, int accountPort) {
74
75         accountClient.addHandler(new AccountHandler());
76         try {
77             accountClient.startClient(
78                     new InetSocketAddress(accountAddress, accountPort));
79         } catch (InterruptedException e) {
80             // TODO Auto-generated catch block
81             e.printStackTrace();
82         }
83     }
84
85     private Cbor<HashMap<Object, Object>> cbor = new Cbor<HashMap<Object, Object>>();
86
87     @Override
88     public void channelRead(ChannelHandlerContext ctx, Object msg)
89             throws Exception {
90
91         if (msg instanceof CoapRequest) {
92             CoapRequest request = (CoapRequest) msg;
93             switch (request.getUriPath()) {
94                 // This handler only used for initial handshake
95                 case Constants.AUTH_URI:
96                     HashMap<Object, Object> payloadData = cbor
97                             .parsePayloadFromCbor(request.getPayload(),
98                                     HashMap.class);
99                     request.setPayload(
100                             JSONUtil.writeJSON(payloadData).getBytes(StandardCharsets.UTF_8));
101                     accountClient.getChannelFuture().channel()
102                             .attr(keyAuthClient).set(ctx);
103                     accountClient.sendRequest(request);
104                     return;
105
106                 case Constants.KEEP_ALIVE_URI:
107                     super.channelRead(ctx, msg);
108                     return;
109
110                 default:
111                     CoapResponse response = new CoapResponse(
112                             CoapStatus.UNAUTHORIZED);
113                     Logger.e("Sending UNAUTHORIZED to client");
114                     ctx.writeAndFlush(response);
115                     break;
116             }
117         }
118
119         Logger.d("Invalid packet for authenticating");
120         ctx.close();
121     }
122 }