Imported Upstream version 1.1.0
[platform/upstream/iotivity.git] / cloud / interface / src / main / java / org / iotivity / cloud / ciserver / protocols / CoapAuthHandler.java
1 /*
2  * //******************************************************************
3  * //
4  * // Copyright 2016 Samsung Electronics All Rights Reserved.
5  * //
6  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7  * //
8  * // Licensed under the Apache License, Version 2.0 (the "License");
9  * // you may not use this file except in compliance with the License.
10  * // You may obtain a copy of the License at
11  * //
12  * //      http://www.apache.org/licenses/LICENSE-2.0
13  * //
14  * // Unless required by applicable law or agreed to in writing, software
15  * // distributed under the License is distributed on an "AS IS" BASIS,
16  * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * // See the License for the specific language governing permissions and
18  * // limitations under the License.
19  * //
20  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21  */
22 package org.iotivity.cloud.ciserver.protocols;
23
24 import java.net.InetSocketAddress;
25 import java.nio.charset.StandardCharsets;
26 import java.util.HashMap;
27 import java.util.Map;
28
29 import org.iotivity.cloud.base.CoapClient;
30 import org.iotivity.cloud.base.protocols.coap.CoapRequest;
31 import org.iotivity.cloud.base.protocols.coap.CoapResponse;
32 import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
33 import org.iotivity.cloud.ciserver.Constants;
34 import org.iotivity.cloud.util.Cbor;
35 import org.iotivity.cloud.util.JSONUtil;
36 import org.iotivity.cloud.util.Logger;
37
38 import io.netty.channel.ChannelDuplexHandler;
39 import io.netty.channel.ChannelHandler.Sharable;
40 import io.netty.channel.ChannelHandlerContext;
41 import io.netty.channel.SimpleChannelInboundHandler;
42 import io.netty.util.AttributeKey;
43
44 @Sharable
45 public class CoapAuthHandler extends ChannelDuplexHandler {
46
47     private static final AttributeKey<ChannelHandlerContext> keyAuthClient = AttributeKey
48             .newInstance("authCtx");
49
50     private class AccountHandler
51             extends SimpleChannelInboundHandler<CoapResponse> {
52
53         @Override
54         public void channelRead0(ChannelHandlerContext ctx, CoapResponse msg)
55                 throws Exception {
56             Logger.d("Receive response from account, forward to client");
57
58             ChannelHandlerContext ctxToDevice = ctx.channel()
59                     .attr(keyAuthClient).get();
60
61             if (msg.getResponseCode() == CoapStatus.CREATED) {
62                 Map<String, String> response = JSONUtil.parseJSON(
63                         new String(msg.getPayload(), StandardCharsets.UTF_8));
64
65                 if (response != null) {
66                     String userId = response.get("userid");
67                     if (userId != null) {
68                         ctxToDevice.channel().attr(Constants.Attribute_UserId)
69                                 .set(userId);
70                     }
71                     msg.setPayload(cbor.encodingPayloadToCbor(response));
72
73                     CoapAuthHandler authHandler = ctxToDevice.channel()
74                             .pipeline().get(CoapAuthHandler.class);
75
76                     ctxToDevice.channel().pipeline().remove(authHandler);
77                 }
78             }
79
80             ctxToDevice.writeAndFlush(msg);
81
82             if (msg.getResponseCode() != CoapStatus.CREATED)
83                 ctxToDevice.close();
84         }
85
86         @Override
87         public void exceptionCaught(ChannelHandlerContext ctx,
88                 Throwable cause) {
89             cause.printStackTrace();
90             ctx.close();
91         }
92     }
93
94     private CoapClient asClient = new CoapClient();
95
96     public CoapAuthHandler() {
97
98         asClient.addHandler(new AccountHandler());
99
100     }
101
102     public void startHandler(String acAddress, int acPort) throws Exception {
103         asClient.startClient(new InetSocketAddress(acAddress, acPort));
104     }
105
106     public void stopHandler() throws Exception {
107         asClient.stopClient();
108     }
109
110     private Cbor<HashMap<Object, Object>> cbor = new Cbor<HashMap<Object, Object>>();
111
112     @Override
113     public void channelRead(ChannelHandlerContext ctx, Object msg)
114             throws Exception {
115
116         if (msg instanceof CoapRequest) {
117             CoapRequest request = (CoapRequest) msg;
118             String uriPath = request.getUriPath();
119             if (uriPath != null) {
120                 switch (uriPath) {
121                     // This handler only used for initial handshake
122                     case Constants.AUTH_URI:
123                         HashMap<Object, Object> payloadData = cbor
124                                 .parsePayloadFromCbor(request.getPayload(),
125                                         HashMap.class);
126                         String writejson = JSONUtil.writeJSON(payloadData);
127                         if (writejson != null) {
128                             request.setPayload(
129                                     writejson.getBytes(StandardCharsets.UTF_8));
130                             asClient.getChannelFuture().channel()
131                                     .attr(keyAuthClient).set(ctx);
132                             asClient.sendRequest(request);
133                         }
134                         return;
135
136                     case Constants.KEEP_ALIVE_URI:
137                         super.channelRead(ctx, msg);
138                         return;
139
140                     default:
141                         CoapResponse response = new CoapResponse(
142                                 CoapStatus.UNAUTHORIZED);
143                         Logger.e("Sending UNAUTHORIZED to client");
144                         ctx.writeAndFlush(response);
145                         break;
146                 }
147             }
148         }
149
150         Logger.d("Invalid packet for authenticating");
151         ctx.close();
152     }
153 }