deep mods
[feisty_meow.git] / octopi / library / tests_octopus / t_security.cpp
1 /*****************************************************************************\
2 *                                                                             *
3 *  Name   : octopus security test                                             *
4 *  Author : Chris Koeritz                                                     *
5 *                                                                             *
6 *  Purpose:                                                                   *
7 *                                                                             *
8 *    Checks out the login support for octopus.  This just exercises the base  *
9 *  support which doesn't perform any extra verification on the user.          *
10 *                                                                             *
11 *******************************************************************************
12 * Copyright (c) 2002-$now By Author.  This program is free software; you can  *
13 * redistribute it and/or modify it under the terms of the GNU General Public  *
14 * License as published by the Free Software Foundation; either version 2 of   *
15 * the License or (at your option) any later version.  This is online at:      *
16 *     http://www.fsf.org/copyleft/gpl.html                                    *
17 * Please send any updates to: fred@gruntose.com                               *
18 \*****************************************************************************/
19
20 #include <basis/astring.h>
21 #include <basis/mutex.h>
22 #include <structures/static_memory_gremlin.h>
23 #include <octopus/entity_defs.h>
24 #include <octopus/infoton.h>
25 #include <octopus/octopus.h>
26 #include <octopus/tentacle.h>
27 #include <application/application_shell.h>
28 #include <loggers/console_logger.h>
29 #include <structures/static_memory_gremlin.h>
30 #include <sockets/internet_address.h>
31 #include <tentacles/login_tentacle.h>
32 #include <tentacles/simple_entity_registry.h>
33
34 //////////////
35
36 astring base_list[] = { "cli", "simp" };
37
38 SAFE_STATIC_CONST(string_array, simp_classifier, (2, base_list))
39
40 class simple_infoton : public infoton
41 {
42 public:
43   astring futzle;
44
45   simple_infoton() : infoton(simp_classifier()) {}
46
47   virtual void pack(byte_array &packed_form) const {
48     futzle.pack(packed_form);
49   }
50   virtual bool unpack(byte_array &packed_form) {
51     if (!futzle.unpack(packed_form)) return false;
52     return true;
53   }
54   virtual int packed_size() const { return futzle.length() + 1; }
55   virtual clonable *clone() const { return new simple_infoton(*this); }
56
57 private:
58 };
59
60 //////////////
61
62 // provides a simple service to allow us to test whether the security is
63 // working or not.
64
65 class simple_tentacle : public tentacle
66 {
67 public:
68   simple_tentacle() : tentacle(simp_classifier(), true) {}
69
70   virtual outcome reconstitute(const string_array &classifier,
71           byte_array &packed_form, infoton * &reformed) {
72     reformed = NULL_POINTER;
73     if (classifier != simp_classifier()) return NO_HANDLER;
74     reformed = new simple_infoton;
75     if (!reformed->unpack(packed_form)) {
76       WHACK(reformed);
77       return GARBAGE;
78     }
79     return OKAY;
80   }
81
82   virtual outcome consume(infoton &to_chow,
83           const octopus_request_id &formal(item_id), byte_array &transformed) {
84     transformed.reset();
85     if (to_chow.classifier() != simp_classifier()) return NO_HANDLER;
86     // consume without doing anything.
87     return OKAY;
88   }
89
90   virtual void expunge(const octopus_entity &formal(to_zap)) {}
91 };
92
93 //////////////
94
95 //hmmm: this test should do a sample login octopus and do a login, reside for
96 //      a while, log out, do another one, let it time out, try to access
97 //      something with dead id hoping to be rejected, etc.
98
99 class test_octopus_security : public application_shell
100 {
101 public:
102   test_octopus_security() : application_shell(class_name()) {}
103   DEFINE_CLASS_NAME("test_octopus_security");
104   virtual int execute();
105 };
106
107 int test_octopus_security::execute()
108 {
109   octopus logos("local", 18 * MEGABYTE);
110   simple_tentacle *tenty = new simple_tentacle;
111   logos.add_tentacle(tenty);
112   tenty = NULL_POINTER;  // octopus has charge of this now.
113
114   // turn on security in logos.
115   simple_entity_registry *guardian = new simple_entity_registry;
116   logos.add_tentacle(new login_tentacle(*guardian), true);
117
118   // create an entity to work with.
119   octopus_entity jimbo("localhost", application_configuration::process_id(), 128, 982938);
120   octopus_request_id req1(jimbo, 1);
121
122   // add the user jimbo.
123   guardian->add_entity(jimbo, byte_array());
124
125   // create a piece of data to try running on tentacle.
126   simple_infoton testose;
127   simple_infoton *testose_copy = new simple_infoton(testose);
128
129   // test that the simple tentacle allows the op.
130   outcome ret = logos.evaluate(testose_copy, req1);
131   if (ret != tentacle::OKAY)
132     deadly_error(class_name(), "first test",
133         astring("the operation failed with an error ")
134             + tentacle::outcome_name(ret));
135
136   // create another entity to work with.
137   octopus_entity burfo("localhost", application_configuration::process_id(), 372, 2989);
138   octopus_request_id req2(burfo, 1);
139
140   // try with an unlicensed user burfo...
141   testose_copy = new simple_infoton(testose);
142   ret = logos.evaluate(testose_copy, req2);
143   if (ret == tentacle::OKAY)
144     deadly_error(class_name(), "second test",
145         astring("the operation didn't fail when it should have."));
146   else if (ret != tentacle::DISALLOWED)
147     deadly_error(class_name(), "second test",
148         astring("the operation didn't provide the proper outcome, it gave: ")
149             + tentacle::outcome_name(ret));
150
151   // remove the user jimbo.
152   guardian->zap_entity(jimbo);
153
154   // test that jimbo fails too now.
155   testose_copy = new simple_infoton(testose);
156   ret = logos.evaluate(testose_copy, req1);
157   if (ret == tentacle::OKAY)
158     deadly_error(class_name(), "third test",
159         astring("the operation didn't fail when it should have."));
160   else if (ret != tentacle::DISALLOWED)
161     deadly_error(class_name(), "third test",
162         astring("the operation didn't provide the proper outcome, it gave: ")
163             + tentacle::outcome_name(ret));
164
165   // add the user burfo in now instead.
166   guardian->add_entity(burfo, byte_array());
167
168   // test that burfo works.
169   testose_copy = new simple_infoton(testose);
170   ret = logos.evaluate(testose_copy, req2);
171   if (ret != tentacle::OKAY)
172     deadly_error(class_name(), "fourth test",
173         astring("the operation failed with an error ")
174         + tentacle::outcome_name(ret));
175
176   log("octopus:: security works for those functions tested.");
177
178   WHACK(guardian); 
179
180   return 0;
181 }
182
183 HOOPLE_MAIN(test_octopus_security, )
184