Cannot connect to mongodb usign mongoengine with read(only) access - python

I have working CLI tool created with mongoengine running on linux environment
MongoDB = 3.4.1
Python = 2.7.5
PyMongo = 3.4.0
MongoEngine = 0.11.0
I am connecting to database
with information in .ini file that looks like so:
[DATABASE]
uri=mongodb://%(user)s:%(password)s#%(host)s/%(dbname)s
dbname=myapp
user=
host=localhost
password=
In Python:
DB_CONN = mongoengine.connect(conf['dbname'], host=conf['uri'])
There are currently two users in database. User usrRO that have read role
and user usrRW that have readWrite role. When connecting to db using
user usrRW name and password in .ini file everything works.
But connecting with user usrRO credentials (user usrRO can read data from mongo CLI interface) leads to:
pymongo.errors.OpeartionFailure: not authorized on myapp to execute command
{ createIndexes: <collection_name>,
indexes: [ { unique: true,
backgroung: false,
sparse: false,
key: { name: 1 },
name: "name_1" } ],
writeConcern: {} }
Is there any way to use users usrRO credentials, or any other way to connect
to database with ready only privileges using mongoengine ?

I found the answer in the mongo-engine gitlab issues.
Simply add
'auto_create_index': False
to your objects meta. This might not work for complex object structures.

Related

Firebase Realtime Database Adding/Removing/Updating/Retrieving Data

So, I wanted to move my local database to the Firebase by using Firebase's Realtime Database feature, however, I am struggling a bit as I am completely new to Firebase, and I am using the library called 'pyrebase'
What I am looking for:
database {
userid1 {
mail:"email1"
},
userid2 {
mail:"email2"
},
userid3 {
mail:"email3"}
...
}
My first question is regarding to how to create such structure using Firebase?
If such structure in the realtime database was accomplished, how to update any specific userid's data?
If wanted any of the user to be deleted from the system by just using their userid, how is it done?
And lastly, which is very important, if wanted to retrieve any of the user emails by looking through their userid, how is it retrieved?
What I have done so far:
I have created the realtime database so far
Downloaded and integrated the credentials
p.s literally in need of source related to Firebase.
So, I have finally figured out how to do all of these as shown below:
Inserting Data:
from firebase import firebase
firebase = firebase.FirebaseApplication('https://xxxxx.firebaseio.com/', None)
data = { 'Name': 'Vivek',
'RollNo': 1,
'Percentage': 76.02
}
result = firebase.post('/python-sample-ed7f7/Students/',data)
print(result)
Retrieving Data:
from firebase import firebase
firebase = firebase.FirebaseApplication('https://xxxx.firebaseio.com/', None)
result = firebase.get('/python-sample-ed7f7/Students/', '')
print(result)
Updating Data:
from firebase import firebase
firebase = firebase.FirebaseApplication('https://xxxx.firebaseio.com/', None)
firebase.put('/python-sample-ed7f7/Students/-LAgstkF0DT5l0IRucvm','Percentage',79)
print('updated')
Delete Data:
from firebase import firebase
firebase = firebase.FirebaseApplication('https://xxxx.firebaseio.com/', None)
firebase.delete('/python-sample-ed7f7/Students/', '-LAgt5rGRlPovwNhOsWK')
print('deleted')

Azure Flask App Services resource not passing Environment Variables

I am trying to inject Environment Variables into an Azure "App Services" Flask resource.
Note: I am aware that some use files to set up environment variables. I may look into that in the future, but for now I'm trying to do this without managing files.
Per the manual, I added the environment variables as "app settings," on the portal page.
And I can see that they have been set correctly with the Azure CLI command:
az webapp config appsettings list --name <redacted> --resource-group <redacted>
which outputs:
{
"name": "DB.DATABASE",
"slotSetting": false,
"value": "<redacted>"
},
{
"name": "DB.DRIVER",
"slotSetting": false,
"value": "{SQL Server Native Client 11.0}"
},
...
My Python code references the variables, which works locally.
from os import environ
driver = environ.get('DB.DRIVER')
server = environ.get('DB.SERVER')
user_id = environ.get('DB.USER_ID')
password = environ.get('DB.PASSWORD')
database = environ.get('DB.DATABASE')
trusted_connection = environ.get('DB.TRUSTED_CONNECTION')
print(f'driver: {driver}')
print(f'server: {server}')
print(f'user_id: {user_id}')
and the output, in the Azure log stream is:
2020-10-05T17:08:01.172742838Z driver: None
2020-10-05T17:08:01.172767338Z server: None
2020-10-05T17:08:01.172772538Z user_id: None
What, please, am I missing from this procedure? It seemed so simple, but it just fails with no error message.

firebase_admin prints None but I have data in db and permission is allow all [duplicate]

I have a chat app using Firebase that keeps on having a
setValue at x failed: DatabaseError: permission denied
error every time I type a message.
I set my Database to be public already:
service cloud.firestore {
match /databases/{database}/documents {
match /{allPaths=**} {
allow read, write: if request.auth.uid != null;
}
}
}
Is it something from within my chat reference?
private void displayChat() {
ListView listOfMessage = findViewById(R.id.list_of_message);
Query query = FirebaseDatabase.getInstance().getReference();
FirebaseListOptions<Chat> options = new FirebaseListOptions.Builder<Chat>()
.setLayout(R.layout.list_item)
.setQuery(query, Chat.class)
.build();
adapter = new FirebaseListAdapter<Chat>(options) {
#Override
protected void populateView(View v, Chat model, int position) {
//Get reference to the views of list_item.xml
TextView messageText, messageUser, messageTime;
messageText = v.findViewById(R.id.message_text);
messageUser = v.findViewById(R.id.message_user);
messageTime = v.findViewById(R.id.message_time);
messageText.setText(model.getMessageText());
messageUser.setText(model.getMessageUser());
messageTime.setText(DateFormat.format("dd-MM-yyyy (HH:mm:ss)", model.getMessageTime()));
}
};
listOfMessage.setAdapter(adapter);
}
Your code is using the Firebase Realtime Database, but you're changing the security rules for Cloud Firestore. While both databases are part of Firebase, they are completely different and the server-side security rules for one, don't apply to the other.
When you go the database panel in the Firebase console, you most likely end up in the Cloud Firestore rules:
If you are on the Cloud Firestore rules in the Firebase console, you can change to the Realtime Database rules by clicking Cloud Firestore BETA at the top, and then selecting Realtime Database from the list.
You can also directly go to the security rules for the Realtime Database, by clicking this link.
The security rules for the realtime database that match what you have are:
{
"rules": {
".read": "auth.uid !== null",
".write": "auth.uid !== null"
}
}
This will grant any authenticated user full read and write access to the entire database. Read my answer to this question on more on the security/risk trade-off for such rules: Firebase email saying my realtime database has insecure rules.
change this
request.auth.uid != null
to
request.auth.uid == null
or defined a proper auth mechanism before starting the conversation where user defined by userID

How to authenticate a WAMP connection via a ticket in python

I'm trying to connect to a WAMP bus from a different application that has certain roles configured. The roles are authenticated with a static ticket, so I believe that I need to declare what role I want to connect as and what the associated ticket is. I'm writing this in Python and have most of the component set up, but I can't find any documentation about how to do this sort of authentication.
from autobahn.twisted.component import Component, run
COMP = Component(
realm=u"the-realm-to-connect",
transports=u"wss://this.is.my.url/topic",
authentication={
# This is where I need help
# u"ticket"?
# u"authid"?
}
)
Without the authentication, I'm able to connect to and publish to the WAMP bus when it is running locally on my computer, but that one is configured to allow anonymous users to publish. My production WAMP bus does not allow anonymous users to publish, so I need to authenticate what role this is connecting as. The Autobahn|Python documentation implies that it can be done in Python, but I've only been able to find examples of how to do it in JavaScript/JSON in Crossbar.io's documentation.
the documentation is not very up to date.
With the Component it is necessary to do like that for tickets:
from autobahn.twisted.component import Component, run
component = Component(
realm=u"the-realm-to-connect",
transports=u"wss://this.is.my.url/topic",
authentication={
"ticket": {
"authid": "username",
"ticket": "secrettoken"
}
},
)
Here is some example that can be helpful for you:
https://github.com/crossbario/crossbar-examples/tree/master/authentication
I think you need to use WAMP-Ticket Dynamic Authentication method.
WAMP-Ticket dynamic authentication is a simple cleartext challenge
scheme. A client connects to a realm under some authid and requests
authmethod = ticket. Crossbar.io will "challenge" the client, asking
for a ticket. The client sends the ticket, and Crossbar.io will in
turn call a user implemented WAMP procedure for the actual
verification of the ticket.
So you need to create an additional component to Authenticate users:
from autobahn.twisted.wamp import ApplicationSession
from autobahn.wamp.exception import ApplicationError
class AuthenticatorSession(ApplicationSession):
#inlineCallbacks
def onJoin(self, details):
def authenticate(realm, authid, details):
ticket = details['ticket']
print("WAMP-Ticket dynamic authenticator invoked: realm='{}', authid='{}', ticket='{}'".format(realm, authid, ticket))
pprint(details)
if authid in PRINCIPALS_DB:
if ticket == PRINCIPALS_DB[authid]['ticket']:
return PRINCIPALS_DB[authid]['role']
else:
raise ApplicationError("com.example.invalid_ticket", "could not authenticate session - invalid ticket '{}' for principal {}".format(ticket, authid))
else:
raise ApplicationError("com.example.no_such_user", "could not authenticate session - no such principal {}".format(authid))
try:
yield self.register(authenticate, 'com.example.authenticate')
print("WAMP-Ticket dynamic authenticator registered!")
except Exception as e:
print("Failed to register dynamic authenticator: {0}".format(e))
and add Authentication method in the configuration:
"transports": [
{
"type": "web",
"endpoint": {
"type": "tcp",
"port": 8080
},
"paths": {
"ws": {
"type": "websocket",
"serializers": [
"json"
],
"auth": {
"ticket": {
"type": "dynamic",
"authenticator": "com.example.authenticate"
}
}
}
}
}
]

Extracting BigQuery Data From a Shared Dataset

Is it possible to extract data (to google cloud storage) from a shared dataset (where I have only have view permissions) using the client APIs (python)?
I can do this manually using the web browser, but cannot get it to work using the APIs.
I have created a project (MyProject) and a service account for MyProject to use as credentials when creating the service using the API. This account has view permissions on a shared dataset (MySharedDataset) and write permissions on my google cloud storage bucket. If I attempt to run a job in my own project to extract data from the shared project:
job_data = {
'jobReference': {
'projectId': myProjectId,
'jobId': str(uuid.uuid4())
},
'configuration': {
'extract': {
'sourceTable': {
'projectId': sharedProjectId,
'datasetId': sharedDatasetId,
'tableId': sharedTableId,
},
'destinationUris': [cloud_storage_path],
'destinationFormat': 'AVRO'
}
}
}
I get the error:
googleapiclient.errors.HttpError: https://www.googleapis.com/bigquery/v2/projects/sharedProjectId/jobs?alt=json
returned "Value 'myProjectId' in content does not agree with value
sharedProjectId'. This can happen when a value set through a parameter
is inconsistent with a value set in the request.">
Using the sharedProjectId in both the jobReference and sourceTable I get:
googleapiclient.errors.HttpError: https://www.googleapis.com/bigquery/v2/projects/sharedProjectId/jobs?alt=json
returned "Access Denied: Job myJobId: The user myServiceAccountEmail
does not have permission to run a job in project sharedProjectId">
Using myProjectId for both the job immediately comes back with a status of 'DONE' and with no errors, but nothing has been exported. My GCS bucket is empty.
If this is indeed not possible using the API, is there another method/tool that can be used to automate the extraction of data from a shared dataset?
* UPDATE *
This works fine using the API explorer running under my GA login. In my code I use the following method:
service.jobs().insert(projectId=myProjectId, body=job_data).execute()
and removed the jobReference object containing the projectId
job_data = {
'configuration': {
'extract': {
'sourceTable': {
'projectId': sharedProjectId,
'datasetId': sharedDatasetId,
'tableId': sharedTableId,
},
'destinationUris': [cloud_storage_path],
'destinationFormat': 'AVRO'
}
}
}
but this returns the error
Access Denied: Table sharedProjectId:sharedDatasetId.sharedTableId: The user 'serviceAccountEmail' does not have permission to export a table in
dataset sharedProjectId:sharedDatasetId
My service account now is an owner on the shared dataset and has edit permissions on MyProject, where else do permissions need to be set or is it possible to use the python API using my GA login credentials rather than the service account?
* UPDATE *
Finally got it to work. How? Make sure the service account has permissions to view the dataset (and if you don't have access to check this yourself and someone tells you that it does, ask them to double check/send you a screenshot!)
After trying to reproduce the issue, I was running into the parse errors.
I did how ever play around with the API on the Developer Console [2] and it worked.
What I did notice is that the request code below had a different format than the documentation on the website as it has single quotes instead of double quotes.
Here is the code that I ran to get it to work.
{
'configuration': {
'extract': {
'sourceTable': {
'projectId': "sharedProjectID",
'datasetId': "sharedDataSetID",
'tableId': "sharedTableID"
},
'destinationUri': "gs://myBucket/myFile.csv"
}
}
}
HTTP Request
POST https://www.googleapis.com/bigquery/v2/projects/myProjectId/jobs
If you are still running into problems, you can try the you can try the jobs.insert API on the website [2] or try the bq command tool [3].
The following command can do the same thing:
bq extract sharedProjectId:sharedDataSetId.sharedTableId gs://myBucket/myFile.csv
Hope this helps.
[2] https://cloud.google.com/bigquery/docs/reference/v2/jobs/insert
[3] https://cloud.google.com/bigquery/bq-command-line-tool
Make sure the service account has permissions to view the dataset (and if you don't have access to check this yourself and someone tells you that it does, ask them to double check/send you a screenshot!)

Categories

Resources