identt
PubKeyService.hpp
Go to the documentation of this file.
1 
33 #ifndef _IDENTT_QUERY_PUBKEY_SERVICE_HPP_
34 #define _IDENTT_QUERY_PUBKEY_SERVICE_HPP_
35 
36 #include <query/QueryBase.hpp>
37 #include <store/PubKeyService.hpp>
38 
39 namespace identt {
40 namespace query {
41 
42 template <class HttpServerT>
44  public identt::query::ServiceBase<HttpServerT> {
45 public:
46 
67  identt::utils::SharedTable::pointer stptr,
68  typename std::shared_ptr<HttpServerT> server,
69  ::identt::query::HelpQuery::pointer helpquery,
70  unsigned int scope)
71  : identt::query::ServiceBase<HttpServerT>(IDENTT_SERVICE_SCOPE_HTTP | IDENTT_SERVICE_SCOPE_HTTPS)
72  {
73  if (!(this->myscope & scope)) return; // scope mismatch
74 
75  // Endpoint : GET _matrix/identity/api/v1/pubkey/{pubkey:string}
76 
77  helpquery->add({scope,"GET _matrix/identity/api/v1/pubkey/{pubkey:string}", {
78  "This is the GET version of pubkey",
79  "Required. The ID of the key. This should take the form algorithm:identifier where algorithm",
80  "identifies the signing algorithm, and the identifier is an opaque string."
81  }
82  });
83 
84  server->resource["/_matrix/identity/api/v1/pubkey/([A-z0-9]*)(%3[Aa]|:)(.*)$"]["GET"]
85  =[this,stptr](typename HttpServerT::RespPtr response, typename HttpServerT::ReqPtr request) {
86  IDENTT_PARALLEL_ONE([this,stptr,response,request] {
87  try {
88  LOG(INFO) << request->path;
89  std::string err;
90  PubKeyT pubkey;
91  pubkey.set_algo( request->path_match[1] );
92  pubkey.set_identifier( request->path_match[3] );
93 
94  if (!stptr->is_ready.Get()) throw identt::BadDataException("System Not Ready");
95 
96  // action
98  pkservice.GetPubKeyAction(stptr, &pubkey);
99 
100  // aftermath
101  std::string output;
102  pb2json(&pubkey , output);
103  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
104  } catch (SydentException& e)
105  {
106  int ecode = (e.ecode()>=IDENTT_SYDENT_ERROR_MIN && e.ecode()<=IDENTT_SYDENT_ERROR_MAX) ? e.ecode() : M_UNKNOWN;
107  std::string output = err2json(SydentErrors.at(ecode),e.what());
108  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
109  } catch (identt::JdException& e)
110  {
111  std::string output = err2json(SydentErrors.at(M_UNKNOWN),e.what());
112  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
113  } catch (std::exception& e)
114  {
115  std::string output = err2json(SydentErrors.at(M_UNKNOWN),e.what());
116  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
117  } catch (...)
118  {
119  this->HttpErrorAction(response,request,500,"INTERNAL SERVER ERROR");
120  }
121  });
122  };
123 
124  // Endpoint : GET _matrix/identity/api/v1/pubkey/isvalid
125 
126  helpquery->add({scope, "GET _matrix/identity/api/v1/pubkey/isvalid?public_key=...", {
127  "This is the GET version of pubkey/isvalid",
128  "Check whether a long-term public key is valid.",
129  "Required. The unpadded base64-encoded public key to check.",
130  "Returns json with valid whether the public key is recognised and is currently valid"
131  }
132  });
133 
134  server->resource["/_matrix/identity/api/v1/pubkey/isvalid\\\?(.*)$"]["GET"]
135  =[this,stptr](typename HttpServerT::RespPtr response, typename HttpServerT::ReqPtr request) {
136  IDENTT_PARALLEL_ONE([this,stptr,response,request] {
137  try {
138  LOG(INFO) << request->path;
139  std::string err;
140 
141  PubKeyT pubkey;
142  auto params = urldecode(request->path_match[1]);
143  pubkey.set_public_key( params.at("public_key") );
144 
145  if (!stptr->is_ready.Get()) throw identt::BadDataException("System Not Ready");
146 
147  // action
149  pkservice.GetPubKeyValidAction(stptr, &pubkey);
150 
151  // aftermath
152  std::string output;
153  pb2json(&pubkey , output);
154  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
155  } catch (SydentException& e)
156  {
157  int ecode = (e.ecode()>=IDENTT_SYDENT_ERROR_MIN && e.ecode()<=IDENTT_SYDENT_ERROR_MAX) ? e.ecode() : M_UNKNOWN;
158  std::string output = err2json(SydentErrors.at(ecode),e.what());
159  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
160  } catch (identt::JdException& e)
161  {
162  std::string output = err2json(SydentErrors.at(M_UNKNOWN),e.what());
163  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
164  } catch (std::exception& e)
165  {
166  std::string output = err2json(SydentErrors.at(M_UNKNOWN),e.what());
167  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
168  } catch (...)
169  {
170  this->HttpErrorAction(response,request,500,"INTERNAL SERVER ERROR");
171  }
172  });
173  };
174 
175  // Endpoint : GET _matrix/identity/api/v1/pubkey/ephemeral/isvalid
176 
177  helpquery->add({scope, "GET _matrix/identity/api/v1/pubkey/ephemeral/isvalid?public_key=...", {
178  "This is the GET version of pubkey/ephemeral/isvalid",
179  "Check whether a short-term public key is valid.",
180  "Required. The unpadded base64-encoded public key to check.",
181  "Returns json with valid whether the public key is recognised and is currently valid"
182  }
183  });
184 
185  server->resource["/_matrix/identity/api/v1/pubkey/ephemeral/isvalid\\\?(.*)$"]["GET"]
186  =[this,stptr](typename HttpServerT::RespPtr response, typename HttpServerT::ReqPtr request) {
187  IDENTT_PARALLEL_ONE([this,stptr,response,request] {
188  try {
189  LOG(INFO) << request->path;
190  std::string err;
191 
192  PubKeyT pubkey;
193  auto params = urldecode(request->path_match[1]);
194  pubkey.set_public_key( params.at("public_key") );
195 
196  if (!stptr->is_ready.Get()) throw identt::BadDataException("System Not Ready");
197 
198  // action
200  pkservice.GetEphemeralValidAction(stptr, &pubkey);
201 
202  // aftermath
203  std::string output;
204  pb2json(&pubkey , output);
205  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
206  } catch (SydentException& e)
207  {
208  int ecode = (e.ecode()>=IDENTT_SYDENT_ERROR_MIN && e.ecode()<=IDENTT_SYDENT_ERROR_MAX) ? e.ecode() : M_UNKNOWN;
209  std::string output = err2json(SydentErrors.at(ecode),e.what());
210  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
211  } catch (identt::JdException& e)
212  {
213  std::string output = err2json(SydentErrors.at(M_UNKNOWN),e.what());
214  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
215  } catch (std::exception& e)
216  {
217  std::string output = err2json(SydentErrors.at(M_UNKNOWN),e.what());
218  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
219  } catch (...)
220  {
221  this->HttpErrorAction(response,request,500,"INTERNAL SERVER ERROR");
222  }
223  });
224  };
225 
226  // Endpoint : POST _matrix/identity/api/v1/sign-{algo:string}
227  helpquery->add({scope,"POST _identt/identity/api/v1/sign-{algo:string}", {
228  "The identity service will happily sign invitation details with a request-specified ed25519 private key for you",
229  "params : mxid, token, private_key, sender (optional) ",
230  "This blindly sign for client"
231  }
232  });
233 
234  server->resource["/_matrix/identity/api/v1/sign-([A-z0-9]*)(%3[Aa]|:)(.*)$"]["POST"]
235  =[this,stptr](typename HttpServerT::RespPtr response, typename HttpServerT::ReqPtr request) {
236  IDENTT_PARALLEL_ONE([this,stptr,response,request] {
237  try {
238  LOG(INFO) << request->path;
239  std::string err;
240  identt::query::PubKeyT pubkey;
241  pubkey.set_algo( request->path_match[1] );
242  pubkey.set_identifier( request->path_match[3] );
243  bool use_json = this->JsonRequest(request);
244 
245  identt::query::ToSignQueryT query;
246  if (use_json)
247  {
248  int stat = json2pb( request->content.string() , &query , err);
249  if (stat<0) throw SydentException("Bad Json Format",M_BAD_JSON);
250  } else {
251  form2pb( request->content.string() , &query); // throws on error
252  }
253 
254  // validations
255  if (query.mxid().length()==0)
256  throw ::identt::query::SydentException("mxid value required", M_MISSING_PARAMS);
257  if (query.token().length()==0)
258  throw ::identt::query::SydentException("token value required", M_MISSING_PARAMS);
259  if (query.private_key().length()==0)
260  throw ::identt::query::SydentException("private_key value required", M_MISSING_PARAMS);
261 
262  // set things
263  pubkey.set_private_key( query.private_key() );
264  pubkey.set_no_keyring(true);
265  if (query.sender().length()==0)
266  pubkey.set_owner("unknown");
267  else
268  pubkey.set_owner(query.sender());
269 
270  if (!stptr->is_ready.Get()) throw identt::BadDataException("System Not Ready");
271 
272  // action
273  std::string output;
275 
276  // add signature
277  ::identt::query::SignedJson::SignatureListT signatures;
278  pkservice.AddSign(stptr, &query , &pubkey, output, signatures);
279 
280  // aftermath
281  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
282  } catch (SydentException& e)
283  {
284  int ecode = (e.ecode()>=IDENTT_SYDENT_ERROR_MIN && e.ecode()<=IDENTT_SYDENT_ERROR_MAX) ? e.ecode() : M_UNKNOWN;
285  std::string output = err2json(SydentErrors.at(ecode),e.what());
286  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
287  } catch (identt::JdException& e)
288  {
289  std::string output = err2json(SydentErrors.at(M_UNKNOWN),e.what());
290  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
291  } catch (std::exception& e)
292  {
293  std::string output = err2json(SydentErrors.at(M_UNKNOWN),e.what());
294  this->HttpOKAction(response,request,200,"OK","application/json",output,true);
295  } catch (...)
296  {
297  this->HttpErrorAction(response,request,500,"INTERNAL SERVER ERROR");
298  }
299  });
300  };
301 
302  }
303 
304 private:
305 
306 };
307 } // namespace query
308 } // namespace identt
309 
310 #endif // _IDENTT_QUERY_PUBKEY_SERVICE_HPP_
void HttpOKAction(typename HttpServerT::RespPtr response, typename HttpServerT::ReqPtr request, int ec, const char *em, const char *content_type, std::string &payload, bool add_cors)
HttpOKAction : OK Action template.
Definition: ServiceBase.hpp:154
void GetPubKeyValidAction(::identt::utils::SharedTable::pointer stptr, ::identt::query::PubKeyT *pubkey)
GetPubKeyValidAction : Service Endpoint GetPubKeyValid.
Definition: PubKeyService.cc:58
PubKeyService(identt::utils::SharedTable::pointer stptr, typename std::shared_ptr< HttpServerT > server, ::identt::query::HelpQuery::pointer helpquery, unsigned int scope)
PubKeyService : constructor.
Definition: PubKeyService.hpp:66
Sydent Exceptions.
Definition: SydentQuery.hpp:91
void GetPubKeyAction(::identt::utils::SharedTable::pointer stptr, ::identt::query::PubKeyT *pubkey)
GetPubKeyAction : Service Endpoint GetPubKey.
Definition: PubKeyService.cc:43
void HttpErrorAction(typename HttpServerT::RespPtr response, typename HttpServerT::ReqPtr request, int ec, const char *em)
HttpErrorAction : Error Action Template no payload maybe template.
Definition: ServiceBase.hpp:85
Definition: BaseUtils.hpp:52
void pb2json(const google::protobuf::Message *msg, std::string &str)
pb2json : Convert protobuf to json
Definition: ProtoJson.cc:415
Definition: PubKeyService.hpp:42
void GetEphemeralValidAction(::identt::utils::SharedTable::pointer stptr, ::identt::query::PubKeyT *pubkey)
GetEphemeralValidAction : Service Endpoint GetEphemeralValid.
Definition: PubKeyService.cc:77
Definition: ServiceBase.hpp:55
Definition: CryptoBase.hpp:49
Definition: PubKeyService.hpp:43
Definition: BaseUtils.hpp:89
void form2pb(const std::string &form, google::protobuf::Message *msg)
form2pb : Convert url-encoded form to protobuf
Definition: ProtoForm.cc:129
std::unordered_map< std::string, std::string > urldecode(const std::string &text)
urlencode : plain url-encode
Definition: ProtoForm.cc:50
std::string err2json(const std::string errorcode, const std::string error)
err2json : Generate a Json for Error Message
Definition: ProtoJson.cc:511
void AddSign(::identt::utils::SharedTable::pointer stptr, const google::protobuf::Message *result, const ::identt::query::PubKeyT *pubkey, std::string &output, SignatureListT &signatures)
AddSign: Add Signature pb, also adds older signatures.
bool JsonRequest(typename HttpServerT::ReqPtr request)
JsonRequest : Check if request is json from Content-Type and Accept fields.
Definition: ServiceBase.hpp:178
int json2pb(const std::string &json, google::protobuf::Message *msg, std::string &err)
json2pb : Convert json to protobuf
Definition: ProtoJson.cc:446