aboutsummaryrefslogblamecommitdiffstats
path: root/include/NT.h
blob: a24d9d405704392b7a01ffaf0957a6b6c7c4dfcf (plain) (tree)
1
2
3
4
5
6
7
8
9





                  


                                              
                                    
                     
                                    

              




























                                           






                                                     






















                                                                               
                                  
                                                                      

                                                                                                     




                                              










                                                                                                                          












                                                                                    


                                                                                                  






                                                                                                                                                          
                                                                







                                                                                                                                                                              
                                                                                                   

                                                                        
                                                                  







                                                                                                              
















                                                                                                                              





                                                                            













                                                                                                            


                                                                                            


                                                             





















                                                                             
#pragma once
#include <cstdint>
#include <set>
#include <vector>
#include <string>

#if defined(_WIN32) && defined(NT_CONSOLE_APP)
#define NT_API
#elif defined(_WIN32) && defined(NT_EXPORTS)
#define NT_API __declspec(dllexport)
#elif defined(_WIN32)
#define NT_API __declspec(dllimport)
#else
#define NT_API
#endif

enum OBJECT_TYPE {
    MULTIGROUP,
    RELATION,
    TUPLE,
    ATTRIBUTE,
    TRANSACTION
};

enum METHOD {
    OPEN,
    CLOSE,
    PARSE, // To plug a secondary namespace
    SECURITY
};

enum AUTH_CLAIM {
    READ,
    WRITE
};

enum AUTH_METHOD {
    CERTIFICATE,
    PLAIN_TEXT
};

namespace nt
{
	class NT_API ObjectManager
	{
	public:
		class IObject {
		public:
			virtual ~IObject() = default;
		};
        class Multigroup : IObject {};
        class Relation : IObject {};
        class Tuple : IObject {};
        class Transaction : IObject {};
        struct object_type {
            OBJECT_TYPE label;
            // If the object is not durable. E.g.: TRANSACTION
            bool disposable;
            std::set<METHOD> methods;
        };
        struct registry_head {
            uint32_t reference_count;
            uint32_t handle_count;
            struct object_type* type;
            std::vector<std::string> path;
            //security_descriptor to be added later, maybe also a set of labels
        };
        struct registry {
            struct registry_head* head;
            IObject object;
            // TODO: Treat as a list for now, but ideally it's a tree
            struct registry* next;
        };
        struct registry** entries;
        // Looks into this registry and attempts to retrieve the entry
		struct registry* Find(const std::vector<std::string> object_path) { return nullptr; }
	};

    class NT_API PermissionsManager
    {
    public:
        // For validating connections at login
		std::set<AUTH_CLAIM> Firewall(AUTH_METHOD method) { return {}; }
		// For validating permission to an object
		const bool Access(const ObjectManager::registry* object, const void* connection_context) {
			// Checks the security descriptor on the head of the object we find in the ObjectManager::registry
			// Then additionally check other metadata yet to be defined in the connection_context,
			// like user group, policy, etc.
			// Yet to decide if this should be summoned at every attempt to get ahold of an object,
			// that might produce significant overhead. How can we solve this?
			return object != nullptr && connection_context != nullptr;
		}
	};

    class NT_API NamespaceReferenceManager
    {
    };
    
    class NT_API CursorManager
    {
    };
    
    class NT_API IdentityManager
    {
    public:
        // Looks into the methods of the object type and asserts if it can be opened
		const bool CanOpen(ObjectManager::registry* object) { return object != nullptr; }
		const bool CanClose(ObjectManager::registry* object) { return object != nullptr; }
	};

    class NT_API LifecycleManager
    {
    public:
        // If object is not being monitored already, monitors the lifecycle by updating the handle count.
        // Maybe also look at the reference count and kill some categories of disposable objects no longer referenced by other objects, like transactions.
        // Think of other use cases later.
		void Monitor(ObjectManager::registry* object) {}
        // Serializes contention for the change of a mutable reference.
        // This can be used in, for example, the HEAD of a branch to serialize the access.
        // If the object does not causes contention, like a relation (since they are immutable, just like multigroups, all snapshots)
        // then just approve, as they do not cause any contention. Transactions also do not cause any, 
        // the only things that do are mutable reference states in shared sessions,
        // for example: the HEAD of a branch, namespace collisions (creating two branches with the same name, or two multigroups with the same name from the same state, etc),
        // multi-branch atomic commits (which I wish to not have as it damages isolation), 
        // garbage collection of old state (as in, we want to delete an old-enough history to save up space), etc.
		const bool Contention(ObjectManager::registry* object){ return object != nullptr; }
        // The inverse of `Monitor`, stops monitoring.
        // Maybe garbage collect here also if the counters goes to zero.
		void Unmonitor(ObjectManager::registry* object) {}
    };

    class NT_API HandlerManager
    {
    public:
        // This is supposed to represent an authorized access to a certain object in the registry
        // This increases the handle count in the object manager
        // We should consider adding on the object manager a vector of all the handles that refer to an object
		struct handle {
			ObjectManager::registry* object = nullptr;
			void* connection_context = nullptr;
		};
		void DeallocateHandle(struct handle* handle) {}
		struct handle Open(std::vector<std::string> object_path, void* connection_context) {
			ObjectManager objects;
			PermissionsManager permissions;
			IdentityManager identities;
			LifecycleManager lifecycles;
			ObjectManager::registry* retrieved_object = objects.Find((const std::vector<std::string>)object_path);
			if (permissions.Access(retrieved_object, (const void*)connection_context)
				&& identities.CanOpen(retrieved_object)
				&& lifecycles.Contention(retrieved_object)) {
				// Starts monitoring this guy
				lifecycles.Monitor(retrieved_object);
				return { retrieved_object, connection_context }; // Return a successful handle
            }
            else {
                // Return something more algebraic instead of null or an int
                return {};
            };
        }
		bool Close(struct handle *handle) {
			if (handle == nullptr) {
				return false;
			}
			PermissionsManager permissions;
			IdentityManager identities;
			LifecycleManager lifecycles;
			// Somehow grab the object pointer and connection (maybe drop it...) from the handle
			ObjectManager::registry* object = handle->object;
			void* connection_context = handle->connection_context;
			// Checking for permissions here may be relevant.
			// What if we have a handle but no permission? Spooky
			if (permissions.Access(object, connection_context)
				&& identities.CanClose(object)
                // TODO: I think that in this case we do not need to worry about contention.
                // But be careful to evaluate this scenario later.
                //&& LifecycleManager::Contention(retrieved_object)
				) {
				// Stops monitoring this guy
				lifecycles.Unmonitor(object);
                DeallocateHandle(handle);
                return true; // Return a successful handle
            }
            else {
                // Return something more algebraic instead of null or an int.
                // It's kinda bad to not even report what went wrong.
                return false;
            };
        }
    };

    class NT_API WAM
    {
    };

    class NT_API NT
    {
    public:
        bool IsRunning() const;
        void SimulateEntryCall() {};
    };
}