One of our initial customers, Shikshanjali Edutech, required to onboard their partnering NGOs, Corporate firms and Government Schools on the MMN platform. They required each of these partners to be able to communicate with each other and utilise workflows specified by Shikshanjali Edutech on the platform. These workflows would be different from the features offered on the MMN platform and would enable Shikshanjali as an organisation to achieve and monitor their goals at a large scale.

Such an ecosystem where users from different organisations work together to achieve a common goal was not possible in the current version of MMN platform. It was designed with the intent of NGOs signing up as individual entities to perform their non-core activities.

 

Conceptualising a network as an ecosystem

We introduced a new concept called networks in the MMN platform. Networks are independent ecosystems for organisations like Shikshanjali Edutech, that partner with other organisations to thrive towards a common goal in the social sector.

A network would have unique workflows customised for achieving its goals. Its data and user activity would be isolated from users that are outside the network. It would have its own branding on the platform to establish it’s own unique identity on the platform.

 

Building a network into ManageMyNGO

Mapping users and organisations into a Network

The concept of networks as a collection of NGOs and other related organisations was not previously thought of. There would now be actors/users in the application who would belong to networks, for-profits, as well as NGOs.

We created a new entity called organisation to represent different organisational entities, such as NGOs, for-profit etc. under one umbrella. Organisations are associated with networks and users associated with organisations are in turn also associated with networks.

Implementing this concept begins with the ability to store, maintain and utilise these relationships between users, networks and organisations. We used a MySQL database to maintain this information at the database level.

All users of the application are maintained in the users table, all organisations in organisations table and all networks in the networks table. A single user can belong to multiple organisations and a single organisation has multiple users. A single organisation can belong to mutiple networks vice-versa a network has multiple organisations. This establishes many-to-many relationships in organisation_user and network_organisation. These two relationships also form a polymorphic relationship between users and networks through organisations.

 

Extending the designed ACL for Multi-Network Support 

It is also possible that a user or an organisation requires being a part of multiple networks. In such a scenario, the user would be authorised to use the platform differently on the network being accessed.

We extended our existing ACL (Access Control List) implementation to incorporate this requirement. We previously created roles (that signify a group of permissions) which authorise users to perform activities on the platform. A user has a single role in an NGO, and role can belong to multiple users, making it a one-to-many relationship. We stored this relationship in the user_role table in the database. This database had user_id (references the table users) and role_id (references the table roles) as a composite key.

 To incorporate the new requirement, we added a new composite key network_id (references table networks). A user can have now multiple roles, one for each network, symbolising the authorisation a user has in each network. This made the user_role relationship a many-to-many relationship.

 

Independently Access Each network

We can now store and retrieve which users are associated with which organisations and networks. We could also obtain their privileges in each network. However, the application still does not know which role and network should be active for a user at a given point.

To implement this we tweaked the way the user accesses the system. Each network would be given a different URL to reach their platform. Based on which URL the user is accessing the platform with, the application detects which network should be selected as active. Once the network is identified, the role is also identified.

We routed dashboard.shikshanjaliedutech.com and dashboard.managemyngo.com to our server. Both domains (shikshanjaliedutech.com and managemyngo.com) are managed by GoDaddy, we created a subdomain dashboard for both of them by adding an A record in the DNS settings that points to the ManageMyNGO’s AWS EC2 server. We then configured virtual hosts for Apache server running on the EC2 Box. Apache would now launch MMN platform if the server is accessed with either of these URLs (See the vhost.conf attached below).

<VirtualHost *:80>

    ServerName dashboard.managemyngo.com

    ServerAlias dashboard.managemyngo.com

    DocumentRoot /var/www/managemyngo/public

    CustomLog /var/log/apache-logs/dashboard.managemyngo.com_access.log combined
    ErrorLog /var/log/apache-logs/dashboard.managemyngo.com_error.log

    <Directory "/var/www/managemyngo/public">
        AllowOverride All
        Require all granted
    </Directory>

</VirtualHost>

<VirtualHost *:80>

    ServerName dashboard.shikshanjaliedutech.com

    ServerAlias dashboard.shikshanjaliedutech.com

    DocumentRoot /var/www/managemyngo/public

    CustomLog /var/log/apache-logs/dashboard.shikshanjaliedutech.com_access.log combined
    ErrorLog /var/log/apache-logs/dashboard.shikshanjaliedutech.com_error.log

    <Directory "/var/www/managemyngo/public">
        AllowOverride All
        Require all granted
    </Directory>

</VirtualHost>

Once both URLs began opening the MMN platform, we needed to enable the application to detect from the URL which network is trying to be accessed. We wrote a script that runs on accessing the dashboard, it identifies the network from the URL with pattern matching. Post identification it sets the network-name as a session variable for reference in future. (see snippet added to laravel below)

<?php
/**
* referrerNetwork() returns the current network from the URL used to access the platform.
*/
public function referrerNetwork()
{
    $url = url('/');
    if($networkName = $this->getNetworkName($url)) {
      return Network::where('name', $networkName)->first();
    }
    return Network::where('name', 'managemyngo')->first();
}
/**
*   setActiveNetwork() sets the session variables for the currently active network.
*/
public function setActiveNetwork()
{
    $network = $this->referrerNetwork();

    session(['network_name' => $network->name]);
    session(['network_display_name' => $network->display_name]);
    session(['organization_name' => $network->name]);
    session(['network_id' => $network->id]);

    return view('auth.login');
}
/**
*   getNetworkName($url) extracts the networkname from the URL.
*/
public function getNetworkName($url) {
    // extracts the network name from the URL.
}

 

Customising the platform for the each network

Now the application was aware of which network and role are active at a given time. Next step was to customise the platform visually and functionally for Shikshanjali Edutech. Shikshanjali wanted all their users to know that they are accessing the Shikshanjali Edutech network for a specific purpose. It involved showcasing their logos and color schemes to represent the networks own identity.

We stored each networks public assets such as Images (logos) and CSS files (color scheme and styling) separately. Based on which network is active currently, the platform retrieves those assets. The currently active network reference is stored in the session.

<head>
  <!--
    {{ session('network_name') }} echos the currently active network's unique name.
  -->
  <link href="networks/{{ session('network_name') }}/css/theme.css" rel="stylesheet">
</head>

<body>
  <a class="navbar-brand" href="{{ url('/') }}">
    <!--
      {{ session('network_display_name') }} echos the currently active network's display name.
    -->
    {{ session('network_display_name') }}
    <img src="/networks/{{ session('network_name') }}/images/logo-header.png" class="network_logo">
  </a>
</body>

All the functionalities we customised and built specifically for the network were stored and accessed separately. Each view and controller had an additional layer of security to check if the access was authorised for the currently active network. The methods @can and @cannot provided out-of-box with Laravel 5.4 make this implementation seamless. (see snippet below)

<!-- session('network_name') stores name of the active network -->

<!-- Checks if logged in user has privileges to see the active network's dashboard -->
@can('see-' . session('network_name') . '-dashboard')
<div class="col-md-7 col-lg-7 col-sm-12 col-xs-12 text-left">
	<!-- includes currently active network's announcements view -->
	@include('dashboard.' . session('network_name') . '.announcements')
	<br>
	@include('dashboard.' . session('network_name') . '.messages')
</div>
@endcan

 

ManageMyNGO is capable of providing applications with unique workflows to large scale organisations in the social sector that require working with multiple organisations and human resource inside and outside its organisational structure. To know more about the becoming an independent network on ManageMyNGO tech platform get in touch with Abhishek, our Product Researcher. If you have a software that requires a similar implementation and you need to consult us for the same, get in touch with Nishanth KD, our Technical lead.