# Onli ID: Owners
*This is a onli-id-service repository managed by Buf*
The onli-id-service is a grpc service that Appliance Owners & Developers (aka Masters) can use to manage their Users.
This service requires Master credentials that are issued by Onli Administrators.

## Concepts
- Masters are power users that access and manage Appliance resources. Masters control the context of user objects.
- Members are owners that are a part of an Appliance. Members control the identity of their user object.
- Owners possess Vaults and an Onli ID. Vaults store genomes. Onli IDs consist of a user object and a Gene.

> Onli ID runs on the cloudMode storage framework. This means every object has three sections or set of values(called entities); Identity, Content and Context. The data stored in Identity is controlled by the Owner. Context contains Appliance controlled information. The key `context.appliances` is a dynamic key-value portion that appliance developers can use that is a part of the Owners User Object. It is up to the appliance developers to create and maintain the data in this section. Storing context dependent data in `context.appliances` is an excellent way to extend the owners attributes for your Appliance.

## Methods
1. [userApi.CreateOwner](https://onli.support/raw/proto/onli-id/buf/#CreateOwner):
	CreateOwner is used to create a new owner. To CreateOwner, you need an `onli_you_id`.
	The onli_you_ids are minted by Onli Administrators and provided to the Appliance Owner.
	Each `onli_you_id` can be used to create a new owner and add them as a member of your Appliance.
	You need to provide an Email and Phone number in the request. A confirmation Email and SMS will be sent which will be used by the potential Owner in the BuildYou phase.
2. [userApi.GetOwner](https://onli.support/raw/proto/onli-id/buf/#GetOwner):
	GetOwner is used to get an Owners identity and context.
3. [userApi.FetchOwner](https://onli.support/raw/proto/onli-id/buf/#FetchOwner):
	FetchOwner is used to fetch selective attributes from an owner's identity and context. The condition in the input can either be `full` or any single variable from either identity or context.appliance. Examples: `"condition": "full"`, `"condition": "identity.status"`
4. [userApi.ListOwner](https://onli.support/raw/proto/onli-id/buf/#ListOwner):
	ListOwner is used to list selective attributes from an owner's identity and context. The condition can be used as described in FetchOwner docs. The meta in the input can be used for pagination and sorting of the response.
5. [userApi.UpdateOwner](https://onli.support/raw/proto/onli-id/buf/#UpdateOwner):
	UpdateOwner is used to update the context of the owner.
6. [userApi.AskToAddOwner](https://onli.support/raw/proto/onli-id/buf/#AskToAddOwner):
	AskToAddOwner is a part of the AddAppliance workflow; use this method for existing Owners that aren't yet a member of your Appliance. AskToAddOwner sends a notification to the owner which can invoke the AcceptAppliance rpc to accept the request. Owners use their OnliID to accept the request and become members of your Appliance.
7. [userApi.AuthLog](https://onli.support/raw/proto/onli-id/buf/#AuthLog):
    Utilize accounting by retrieving a specific auth log from the database using auth_log_id
8. [userApi.AskAssetBalance](https://onli.support/raw/proto/onli-id/buf/#AskAssetBalance):
    AskAssetBalance is called by master to request the owner to share their vault balances
    The owner is sent a notification and can authorize with UpdateAssetBalance
9. [userApi.AuthenticateOwner](https://onli.support/raw/proto/onli-id/buf/#AuthenticateOwner):
    AuthenticateOwner is a bi-directional stream request from a master to an owner
    and it stays open for a set-interval,
    after that it expires and the stream exits.
10. [userApi.AuthorizeBehavior](https://onli.support/raw/proto/onli-id/buf/#AuthorizeBehavior):
    AuthorizeBehavior is a bi-directional stream that masters use to confirm explicit behaviors from owners
    Similar process to AuthenticateOwner, the only requirement is that the behavior exists under the user type in Onli ID

## How to use the Onli ID Owner API?
1. To use this API, you need Master credentials from Onli. The credentials include `user_id` and `app_key`. These credentials need to be passed as Metadata headers in each request.
2. Once you have the credentials, you can test this buf repo using API platforms like Postman, insomnia, etc. You can also use it in any language on your app. You can get the supported SDK from here: [Buf SDKs](https://buf.build/onlicorp/onli-id/sdks)

## Examples
Below are some helpful examples of how to assemble messages for each request and typical responses.

### CreateOwner
```json
// Request
{
    "data": {
        "identity": {
            "onli_you_id": "usr-d0db0415-4238-5a0e-a46b-c4dd39d86be3",
            "app_symbol": "ENGMA",
            "app_key": "hyu774",
            "email": "juan@onli.one",
            "phone": "17787788877"
        },
        "context": {
            "appliances": {
                "ENGMA": {
                    "user_class": "t1",
                    "extra": "{\"group\": \"onlidevs\"}"
                }
            }
        }
    }
}
```
```json
// Response
{
    "status": 0,
    "identity": {
        "onli_you_id": "usr-dc8be5ae-8593-5d91-8889-6bda935336f4"
    }
}
```
### GetOwner
```json
// Request
{
    "onli_you_id": "usr-d0db0415-4238-5a0e-a46b-c4dd39d86be3",
    "app_symbol": "ENGMA",
}
```
```json
// Response
{
    "status": 0,
    "data": {
        "identity": {
            "onli_you_id": "usr-dc8be5ae-8593-5d91-8889-6bda935336f4",
            "first_name": "Sherlock",
            "alt_name": "thinkpipe",
            "last_name": "Holmes",
            "email": "sherlock@holmes.com",
            "alt_email": "sleuth@ing.com",
            "username": "1deduction",
            "address": "221B Baker Street",
            "address_2": "123 Street",
            "city": "London",
            "state": "Manchester",
            "postal": "22455",
            "country": "England",
            "phone": "+447975777666",
            "company": "",
            "status": "STATUS_ACTIVE"
        },
        "context": {
            "appliances": {
                "ENGMA": {
                    "user_class": "T1",
                    "status": "STATUS_APP_ACTIVE",
                    "extra": "{\"group\": \"detective\"}"
                }
            }
        }
    }
}
```
### FetchOwner
```json
// Request
{
    "onli_you_id": "usr-dc8be5ae-8593-5d91-8889-6bda935336f4",
    "app_symbol": "ENGMA",
    "condition": "identity.email"
}
```
```json
// Response
{
    "status": 0,
    "data": {
        "identity": {
            "email": "sherlock@holmes.com",
        }
    }
}
```

### ListOwner
```json
// Request
{
    "app_symbol": "ENGMA",
    "condition": "identity.email",
    "meta": {
        "limit": 2,
        "offset": 0
    }
}
```
```json
// Response
{
    "data": [
        "identity": {
            "onli_you_id": "usr-dc8be5ae-8593-5d91-8889-6bda935336f4",
            "email": "sherlock@holmes.com",
        },
        "identity": {
            "onli_you_id": "usr-rj8be5ae-8593-5d91-8889-6bda935337g6",
            "email": "enola@holmes.com",
        }
    ],
    "status": 0,
    "meta": {
        "limit": 2,
        "offset": 0,
    }
}
```
### UpdateOwner
```json
// Request
{
    "data": {
        "identity": {
            "onli_you_id": "usr-dc8be5ae-8593-5d91-8889-6bda935336f4",
            "app_symbol": "ENGMA",
        },
        "context": {
            "appliances": {
                "ENGMA": {
                    "status": 2,
                    "extra": "{\"group\": \"day-trader\"}"
                }
            }
        }
    }
}
```
```json
// Response
{
    "status": 0,
    "identity": {
        "onli_you_id": "usr-dc8be5ae-8593-5d91-8889-6bda935336f4"
    }
}
```

### AskToAddOwner
```json
// Request
{
    "data": {
        "onli_you_id": "usr-dc8be5ae-8593-5d91-8889-6bda935336f4",
        "app_symbol": "SPECI",
        "appliance": {
            "user_class": "specie-user-class",
            "extra": "{\"foo\": \"bar\"}"
        }
    }
}
```
```json
// Response
{
    "status": 0,
    "identity": {
        "onli_you_id": "usr-dc8be5ae-8593-5d91-8889-6bda935336f4"
    }
}
```
### AuthLog
```json
// Request
{
    "app_symbol": "ABCDE",
    "auth_log_id": "example auth-log-id"
}
```
```json
// Response
{
    "AuthLogId": "example auth-log-id",
    "TS": "1738763781676826463",
    "WhichSecurityMethod": "ask_to_move_stream",
    "WhichAppliance": "ABCDE",
    "GeoData": null,
    "Request": "{ "to ": "example usr-id ", "note ":{ "behavior ": "move ", "body ": "Accept ask to move request from ABCDE "}, "app_symbol ": "ABCDE ", "amount ":1}",
    "Response": "{ "ask_to_move_id ": "example ask-to-move-id ", "pkg_tag ": "e484868e-89db-406e-882f-321e9341977c ", "to ": "example usr-id ", "note ":{ "behavior ": "move ", "body ": "Accept ask to move request from ABCDE "}, "amount ":1, "app_symbol ": "ABCDE ", "asset_balance ":8, "notified_at ":1738763619, "status ":3, "expires_at ":1754531619, "behavior_status ":true, "authorization_status ":true, "auth_log_id ": "example auth-log-id "}",
    "Err": ""
}
```

### AskAssetBalance
```json
// Request
{
    "app_symbol": "ABCDE",
    "owner": "example user_id"
}
```
```json
// Response
{
    "AssetBalances": [
        {
            "balance": "2009",
            "vault_type": "desktop"
        },
        {
            "balance": "51",
            "vault_type": "cloud"
        }
    ],
    "owner": "example usr-id",
    "auth_log_id": "example auth-log-id",
    "app_symbol": "ABCDE",
    "status": "AuthenticationStatusACCEPTED"
}
```

### AuthenticateOwner
```json
// Request
{
    "owner": "example user_id",
    "app_symbol": "ABCDE",
    "body": "Please Confirm Request to Authenticate from ABCDE",
    "rev_string": "96"
}
```
```json
// Response
{
    "owner": "example usr-id",
    "auth_log_id": "example auth-log-id",
    "authentication_status": "AuthenticationStatusACCEPTED",
    "auth_type": "REVERSE_MFA",
    "rev_string": "96",
    "app_symbol": "ABCDE",
    "body": "Please Confirm Request to Authenticate from ABCDE",
    "asset_balance": "51"
}
```

### AuthorizeBehavior
```json
// Request
{
    "owner": "example user_id",
    "app_symbol": "ABCDE",
    "note": {
        "behavior": "login",
        "body": "Please Confirm Request to Authorize from ABCDE"
    }
}
```
```json
// Response
{
    "owner": "example usr-id",
    "auth_log_id": "example auth-log-id",
    "authentication_status": "AuthenticationStatusACCEPTED",
    "app_symbol": "ABCDE",
    "note": {
        "behavior": "login",
        "body": "Please Confirm Request to Authorize from ABCDE"
    }
}
```